顺丰接口接入-主要处理下单接口上电子面单上传问题

概述

最近接到一个需求,需要和顺丰接口对接。由于是第一次对接,就需要把所有的流程全部走一遍,从 注册关联API 以及代码测试电子面单审核上线,下面就分开来说明把。本来是想着偷懒来着,作为专业的程序员,能Ctrl + C 加上 Ctrl + V 的,绝对不会有多余的动作,但是发现这个能找到的文章都上年纪了,不适合当下了。

顺丰速运接入

接入肯定是需要看官方的文档的,点击这里看官方的详细接入指引,官网上面说的还是比较详细的,另外还有一个2分钟的视频说明还算是贴心的了。我这边就简单的梳理下,大伙按照官网的来就好。

第一步:注册

登录LaaS开放平台
如果您已有开放平台账号,可直接使用账号密码登录。如果您已有月结管家/速打平台/数据灯塔账号,可选择对应登录方式直接登录。如果您是顺丰内部员工,可选择顺丰工号登录方式完成域账号登录。
如果您是首次与顺丰合作,可通过注册平台账号后登录

顺丰注册

第二步:认证
进入“控制台”,在控制台首页点击【立即认证】,根据实际情况选择“个人认证”或“企业认证”。这里我就不赘述了,大家看下官网就好,我是用的个人认证的,先测试通过再说。点击这里看官方的详细接入指引

第三步:创建应用

在“控制台-业务中心”选择“业务对接-开发者对接”,点击【新建应用】按钮创建应用。每个应用对应您需要接入顺丰服务的单个系统,平台将为每个应用分配独立的对接账号(顾客编码)及密钥(校验码)。

开发者对接

创建应用
创建应用
创建成功
创建成功
关联API
关联所需要的API
这里是我自己关联的API
个人关联的
这个云打印面单转PDF的接口这里先有个印象,后面回用到
基础通用的API
到这里,我们的第一部分认证以及关联就算是搞完了,后面我们就开始上代码了。

SDK下载与说明

丰桥API-SDK下载
点击这里看官方连接,很重要,由于不知道什么时候我这里的文档也过时,看下官方的最保险。
下载 SDK 工具
在这里插入图片描述

下载
下载完成之后,我们看下对应的包
调用测试类
CallExpressServiceTools 是使用 sdk-java 的入口,下载的zip包内json文件夹对应的是丰桥服务接口对应的报文,如下订单使用的报文是\json\EPSJson\EPS.1.COM_RECE_EPS_ORDER.json,请求对应的接口使用对应的请求报文(可以将请求报文的文件放置在 java 工程的目录内,方便测试调用。

下载的zip包 java-demo 目录还有个java版的测试类(TestCallExpressNewAPIService.java),可以在java工程中新建个测试目录如com.sf.test,完整的测试接口调用环境如下截图:
在这里插入图片描述
完整的客户端调用代码如下:

package com.sf.csim.express.test;


import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import com.sf.csim.express.service.CallExpressServiceTools;
import com.sf.csim.express.service.HttpClientUtil;
import com.sf.csim.express.service.IServiceCodeStandard;
import com.sf.csim.express.service.code.ExpressServiceCodeEnum;

public class TestCallExpressNewAPIService {
	
private static final String CLIENT_CODE = "";  //此处替换为您在丰桥平台获取的顾客编码
private static final String CHECK_WORD = "";//此处替换为您在丰桥平台获取的校验码

//沙箱环境的地址
private static final String CALL_URL_BOX = "https://sfapi-sbox.sf-express.com/std/service";
//生产环境的地址
private static final String CALL_URL_PROD = "https://sfapi.sf-express.com/std/service";

	public static void main(String[] args) throws UnsupportedEncodingException {
		/**ExpressServiceCodeEnum     对应速运类-快递APIs   
		   POSTServiceCodeEnum        对应速运类-驿站APIs
		   YJTServiceCodeEnum         对应解决方案-医寄通APIs
		   EPSServiceCodeEnum         对应解决方案-快递管家APIs 
		   详情见code目录下枚举类,客户可自行修改引用的该类
		**/		
            IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER; //下订单
		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ORDER_RESP; //查订单
		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;//订单取消
		// 	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_FILTER_ORDER_BSP;//订单筛选
		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ROUTES;//查路由
		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_GET_SUB_MAILNO;//子单号
		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_QUERY_SFWAYBILL;//查运费
		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_REGISTER_ROUTE;//注册路由	
		//	IServiceCodeStandard standardService = 	
		
		
		 CallExpressServiceTools tools=CallExpressServiceTools.getInstance();    
		
        // set common header
        Map<String, String> params = new HashMap<String, String>();
        
        String timeStamp = String.valueOf(System.currentTimeMillis());
        String msgData =tools.packageMsgData(standardService);
        
        params.put("partnerID", CLIENT_CODE);  // 顾客编码
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode",standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);    
        params.put("msgData", msgData);      
        params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,CHECK_WORD));
        
        String result = HttpClientUtil.post(CALL_URL_BOX, params);
        System.out.println("===调用地址 ==="+CALL_URL_BOX);
        System.out.println("===顾客编码 ==="+CLIENT_CODE);
        System.out.println("===返回结果:" +result);
     
	}	

}

代码测试

工程搭建

在项目工程中引入顺丰的SDK
工程结构
Pom 文件

<dependency>
   <groupId>com.sf</groupId>
   <artifactId>SF-CSIM-EXPRESS-SDK</artifactId>
   <version>2.1.7</version>
   <scope>system</scope>
   <systemPath>${project.basedir}/src/main/resources/lib/SF-CSIM-EXPRESS-SDK-V2.1.7.jar</systemPath>
</dependency>

对应的调用代码示例

package com.demo.express.sf.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sf.csim.express.service.CallExpressServiceTools;
import com.sf.csim.express.service.HttpClientUtil;
import com.sf.csim.express.service.IServiceCodeStandard;
import com.sf.csim.express.service.code.ExpressServiceCodeEnum;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


public class CallExpressApiService {

    private static final String CLIENT_CODE = "";  //此处替换为您在丰桥平台获取的顾客编码
    private static final String CHECK_WORD = "";//此处替换为您在丰桥平台获取的校验码


    //沙箱环境的地址 -PRO
    private static final String CALL_URL_BOX = "https://sfapi-sbox.sf-express.com/std/service";
    //生产环境的地址 -PRO
    private static final String CALL_URL_PROD = "https://sfapi.sf-express.com/std/service";


    /**
     * 调用参数
     * <pre>
     *     String msgData = "{" +
     *                 "    "cargoDetails":[" +
     *                 "        {          " +
     *                 "            "count":2.365," +
     *                 "             "unit":"个"," +
     *                 "             "weight":6.1," +
     *                 "             "amount":100.5111," +
     *                 "            "currency":"HKD"," +
     *                 "            "name":"护肤品1",           " +
     *                 "            "sourceArea":"CHN"          " +
     *                 "        }]," +
     *                 "    "contactInfoList":[" +
     *                 "        {" +
     *                 "            "address":"广东省深圳市南山区软件产业基地11栋"," +
     *                 "            "contact":"小曾"," +
     *                 "            "contactType":1," +
     *                 "            "country":"CN"," +
     *                 "            "postCode":"580058"," +
     *                 "            "tel":"4006789888"" +
     *                 "        }," +
     *                 "        {" +
     *                 "            "address":"广东省广州市白云区湖北大厦"," +
     *                 "            "company":"顺丰速运"," +
     *                 "            "contact":"小邱"," +
     *                 "            "contactType":2," +
     *                 "            "country":"CN"," +
     *                 "            "postCode":"580058"," +
     *                 "            "tel":"18688806057"" +
     *                 "        }]," +
     *                 "    "language":"zh_CN"," +
     *                 "    "orderId":"OrderNum20240612223"" +
     *                 "}";
     * </pre>
     * @param msgData
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createOrder(String msgData) throws UnsupportedEncodingException {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER; //下订单

        CallExpressServiceTools tools = CallExpressServiceTools.getInstance();

        // set common header
        Map<String, String> params = new HashMap<>();

        String timeStamp = String.valueOf(System.currentTimeMillis());

        params.put("partnerID", CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode", standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", tools.getMsgDigest(msgData, timeStamp, CHECK_WORD));


        System.out.println("====调用实际请求:" + params);
        String result = HttpClientUtil.post(CALL_URL_BOX, params);

        System.out.println("====调用丰桥的接口服务代码:" + standardService.getCode() + "====");
        System.out.println("===调用地址 ===" + CALL_URL_BOX);
        System.out.println("===顾客编码 ===" + CLIENT_CODE);
        System.out.println("===返回结果:" + result);

        return result;
    }
}

这样子就可以测试了,几乎是按照官方的来的,还是比较简单。

下单接口文档
详细的接口文档地址 ,点击下面的 “下订单接口”
下单接口
说明下:我这个接口后面有个 “上线” 的操作,这个是因为我这边已经审核通过了,最开始这里是有一个测试操作的。

查询接口测试记录
查看测试接口记录

电子面单上传

在下单的接口处,我们会看到有这么一个地方,就是需要上传电子面单,这个东西我也是找了好久,最后发现这个其实是需要我们去调用面单打印的接口,由于我们是第一次调用,就需要去对接下这个接口
电子面单上传处理
配置云打印面单接口
这里我们需要在 基础通用API 关联 云打印面单转PDF接口,这里我是为了测试面单上传,就选择了 “同步” 方式,具体可以看下官方的说明,异步的话,需要自己给一个回调地址。
云打印面单
这里可以看到对应的模板名称
查看对应的模板名称

这个时候,我们就需要去关联云打印的接口了,基于上面的代码,我们增加两个函数:

  • printWayBills 云打印面单打印
  • 获取PDF接口
	/**
     * 调用参数
     * <pre>
     *  {
     *     "templateCode": "fm_150_standard_YJ3CB3FX",  这里是配置的那个打印模板
     *     "version":"2.0",
     *     "fileType":"pdf",
     *     "sync":true,
     *     "documents": [{
     *     "masterWaybillNo": "SF7444480501251"
     *     }]
     *  }
     */
 public static void printWayBills(String msgData) throws UnsupportedEncodingException {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.COM_RECE_CLOUD_PRINT_WAYBILLS; //云打印面单打印2.0接口

        CallExpressServiceTools tools = CallExpressServiceTools.getInstance();

        // set common header
        Map<String, String> params = new HashMap<>();

        String timeStamp = String.valueOf(System.currentTimeMillis());

        params.put("partnerID", CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode", standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", tools.getMsgDigest(msgData, timeStamp, CHECK_WORD));


        System.out.println("====调用实际请求:" + params);
        String result = HttpClientUtil.post(CALL_URL_BOX, params);

        System.out.println("====调用丰桥的接口服务代码:" + standardService.getCode() + "====");
        System.out.println("===调用地址 ===" + CALL_URL_BOX);
        System.out.println("===顾客编码 ===" + CLIENT_CODE);
        System.out.println("===返回结果:" + result);
    }

根据上面 printWayBills 返回值,我们可以拿到对应的pdf文件地址,返回的数据如下:

 {"apiErrorMsg":"","apiResponseID":"00018E79F0AAEE3FE755F4D40823D73F","apiResultCode":"A1000","apiResultData":"{\"obj\":{\"clientCode\":\"YJ3CB3FX\",\"fileType\":\"pdf\",\"files\":[{\"areaNo\":1,\"documentSize\":0,\"pageCount\":0,\"pageNo\":1,\"seqNo\":1,\"token\":\"AUTH_tkv12_f146d1855480549d262b5c46ab0ab597ff20a97d9d0db45c16bedeb4fabd112b012deadd477ee524b1d690ce01baa3cdffbb125a6ccf69b73778dba2eb5157eb73eb03e946a2c01352db378fe2bdea7c95c535a186cf195dc290be8fb7d1e7064e80fa12c5e7757aff35d31ff59b7f55832b73ef3f6a4397c071ef11cba0f8623abd7a376adcd85a3c8e3e8c9b64f903a7d5c55353003625d76f23480fd915464d767f73ba97048cd4aef655f4d970ba\",\"url\":\"https://eos-scp-core-shenzhen-futian1-oss.sf-express.com:443/v1.2/AUTH_EOS-SCP-CORE/print-file-sbox/AAABjnnwq4I40xFIfoVMAJQtjYTrUht8_SF7444480501251_fm_150_standard_YJ3CB3FX_1_1.pdf\",\"waybillNo\":\"SF7444480501251\"}],\"templateCode\":\"fm_150_standard_YJ3CB3FX\"},\"requestId\":\"9c772eb846124800a15edcaf9e0cfea4\",\"success\":true}"}

调用代码,这里需要使用自己的请求参数,用我的是不行的哈

public static void getPDF(String result){
     JSONObject resultJson = JSON.parseObject(result).getJSONObject("apiResultData").getJSONObject("obj");
     JSONObject fileInfo = resultJson.getJSONArray("files").getJSONObject(0);

     try {
         URL noodleUrl = new URL(fileInfo.getString("url"));
         URLConnection connection = noodleUrl.openConnection(); //创建连接
         //设置请求头(下载文件时需要的token,设置在请求头的 X-Auth-token 字段,有效期 24h)
         connection.setRequestProperty("X-Auth-token", fileInfo.getString("token"));

         try ( InputStream in = connection.getInputStream()){
             File outputFile = new File("D:\\test\\"+resultJson.getString("templateCode")+".pdf");
             try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                 IOUtils.copy(in, outputStream);
                 System.out.println("内容已成功写入到文件中。");
             }
         }

     } catch (IOException e) {
         throw new RuntimeException(e.getMessage());
     }
 }

然后在我本地就会有这个文件在,把这个文件转为png,在下单接口上传就好:
截图
最后审核通过的截图
已审核的截图

上线

API状态根据上线流程可分为:

待配置 :根据实际情况完成接口关键属性配置,对于不需要配置的接口,平台默认不显示此状态,直接切换为“测试中”。

测试中 :在沙箱环境自助联调接口。点击【测试】按钮可选择下载API-SDK或使用在线测试工具联调。点击【配置】按钮修改接口属 性,点击【查看】按钮查询已配置的接口属性。

待上线 :平台检测到API已具备切入生产环境条件(接口7天内测试成功3次以上,若为下单接口,需通过面单审核或配置免面单,具体参考面单部分说明)。点击【上线】按钮可完成接口上线。

已上线 :API已切入生产环境条件,可正常调用生产环境接口地址。

:新用户需对接使用云打印接口,上传云打印面单进行审核,审核通过后才能完成下单接口上线操作。

官方说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/495349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Days 35 ElfBoard板对Java的支持

Java作为一种功能强大且广泛应用的编程语言&#xff0c;具有广泛的适应性和实用性。在ELF 1开发板上集成Java支持&#xff0c;无疑将赋予嵌入式开发者更广阔的选择空间&#xff0c;今天就为各位小伙伴详细解析如何在ELF 1开发板上成功部署和运行Java环境。 1.拷贝两个压缩包到E…

FME学习之旅---day14

我们付出一些成本&#xff0c;时间的或者其他&#xff0c;最终总能收获一些什么。 【FME-HOW-TO系列】13 通过重新采样修改栅格像元大小 除了使用RasterResampler转换器进行重采样的操作外&#xff0c;还需要了解不同的插值方法&#xff0c;各方法大概的不同。 可以参考ArcG…

计算机网络(二)物理层

物理层 一、通信基础1.奈氏准则、香农定理2.编码与调制3.电路交换、报文交换、分组交换 二、 传输介质、设备1.导向性传输介质&#xff1a;1.1双绞线1.2 同轴电缆1.3光纤 2.非导向性传输介质&#xff1a; 一、通信基础 信道带宽&#xff1a;信道能通过的最高频率和最低频率之差…

学浪视频提取

经过调查,学浪这个学习平台越来越多人使用了,但是学浪视频官方没有提供下载按钮,为了让这些人能够随时随地的观看视频,于是我钻研学浪视频的下载,终于研究出来了并且做成软件批量版 下面是学浪视频提取的软件,有需要的自己下载一下 链接&#xff1a;https://pan.baidu.com/s/…

Chrome之解决:浏览器插件不能使用问题(十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

[flask]http请求//获取请求头信息+客户端信息

在网站中查询请求头信息&#xff0c;可以通过以下操作进行 右键然后选择检查 进入改页面后选择文档&#xff0c;刷新一下页面就好了 获取所有的请求头信息 print(request.headers, type(request.headers)) 在flask模块中&#xff0c;使用上面的输出函数就可以查看到有关于请求…

软考高级架构师:云原生架构概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

企业计算机服务器中了mkp勒索病毒怎么办,mkp勒索病毒解密流程步骤

在网络技术飞速发展的今天&#xff0c;越来越多的企业走向了数字化办公模式&#xff0c;网络为企业的生产运营提高了效率&#xff0c;为企业带来了极大便利&#xff0c;但网络是一把双刃剑&#xff0c;在为人们提供便利的同时也会带来数据安全问题&#xff0c;网络数据安全一直…

There is no getter for property named ‘deleted‘

实体类在继承BaseEntity的时候,由于没填写deleted参数名导致mybatis报错 这时候要么改application.yml里的mybatis参数&#x1f447; 要么就将BaseEntity基类的delete上加个existfalse&#x1f447;(推荐)

【单例模式】—— C++设计模式【附百度Apollo单例模式详细解读】

参考资料&#xff1a; &#xff08;1&#xff09;单例模式—— 代码随想录 &#xff08;2&#xff09;我给面试官讲解了单例模式后&#xff0c;他对我竖起了大拇指&#xff01; &#xff08;3&#xff09;C 单例模式详解 &#xff08;4&#xff09;单例模式之C实现&#xff0c;…

ssm 房屋销售管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 房屋销售管理系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模…

今天起,Windows可以一键召唤GPT-4了

现在&#xff0c;OpenAI 大模型加持的 Copilot 功能终于登陆 Windows 了。 把 Copilot 按钮放在 Windows 桌面的任务栏&#xff0c;甚至实体键盘上&#xff0c;用大模型提升每个人的生产效率。 美东时间 3 月 21 日周四&#xff0c;生成式 AI 领军的微软又为我们带来了一点小…

浅谈交直流混合微电网能量管理系统关键技术研究综述

摘要&#xff1a;为了提升交直流混合微电网健康有效发展&#xff0c;提高直流互联微电网中分布式电源的能源使用效率&#xff0c;提升区域微电网稳定发展&#xff0c;对交直流混合微电网能量管理系统关键技术进行分析和研究很有必要。文章主要从交直流混合微电网能量管理系统架…

Codigger开发者篇:开启全新的开发体验(二)

在数字化浪潮中&#xff0c;开发者们始终在追求更加高效、便捷的开发工具与环境。Codigger&#xff0c;作为新一代开发、运营、使用私人应用的分布式操作系统&#xff0c;正是为这些追求者们量身打造的利器&#xff0c;Codigger是一个跨时代的颠覆式的创新。今天&#xff0c;我…

贪心算法相关题目

文章目录 1. 什么是贪心&#xff1f;2. 分发饼干3. 摆动序列4. 最大子数组和5. 买卖股票的最佳时机 II6. 跳跃游戏7. 跳跃游戏 II8.K 次取反后最大化的数组和9.加油站10.分发糖果11.柠檬水找零12.根据身高重建队列13.用最少数量的箭引爆气球14. 无重叠区间15.划分字母区间16.合…

腾讯云2核2G服务器CVM S5和轻量应用服务器优惠价格

腾讯云2核2G服务器多少钱一年&#xff1f;轻量服务器61元一年&#xff0c;CVM 2核2G S5服务器313.2元15个月&#xff0c;腾讯云2核2G服务器优惠活动 txyfwq.com/go/txy 链接打开如下图&#xff1a; 腾讯云2核2G服务器价格 轻量61元一年&#xff1a;轻量2核2G3M、3M带宽、200GB月…

JWT认证原理

简介&#xff1a; JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally …

windows-MySQL5.7安装

1.安装包下载 https://downloads.mysql.com/archives/community/&#xff08;社区版下载链接&#xff09; 选择Archives可以下载历史包&#xff0c;此处使用5.7.43 2.解压文件 解压文件到你指定安装的目录&#xff1a;解压完成后在mysql-5.7.43-winx64下新建文件my.ini和d…

护眼台灯哪个牌子最好?五款骨灰级硬核机型推荐!

在快节奏的现代生活中&#xff0c;保护视力、提升学习和工作效率都离不开一盏优质的护眼台灯。然而&#xff0c;市面上的护眼台灯品牌琳琅满目&#xff0c;让人在选择时感到迷茫。为了帮助大家找到最适合自己的护眼台灯&#xff0c;本文将为大家推荐五款具备骨灰级硬核实力的护…

Mac添加和关闭开机应用

文章目录 mac添加和关闭开机应用添加开机应用删除/查看 mac添加和关闭开机应用 添加开机应用 删除/查看 打开&#xff1a;系统设置–》通用–》登录项–》查看登录时打开列表 选中打开项目&#xff0c;点击“-”符号