作为一名常年和电商物流系统打交道的开发者,我太清楚对接多家快递公司面单系统的痛苦了——接口格式不统一、模板维护繁琐、单号回传易出错,光是调试就得耗费大量精力。直到接触了快递100电子面单API,才真正实现了"一次对接,全快递公司通用"的高效开发。今天就带大家从零开始,手把手教你用这套API快速实现快递下单、面单生成与打印功能。
一、为什么选择快递100电子面单打印API?
在聊技术实现前,先说说它解决了开发者的哪些核心痛点:
● 免重复开发:无需逐一对接顺丰、中通、圆通等多家快递公司接口,API已完成60+快递公司电子面单能力聚合,一次集成即可覆盖主流快递品牌。
● 多场景适配:支持网点电子面单、菜鸟电子面单、拼多多等电商平台电子面单等多种类型,支持电商平台授权,一键同步多家电商平台订单。无论是电商商城、ERP系统还是WMS仓储系统都能无缝对接。
● 全链路能力:不仅能打单,还可联动物流轨迹查询、时效预估等功能,实现"打单-发货-跟踪"一体化开发。
● 高可靠性:接口可用性高达99.99%,且提供提供简单易用的模板编辑器。
对于追求开发效率的团队来说,这些优势直接意味着人力成本降低和上线周期缩短。
二、对接前的准备工作
1. 账号与权限申请
首先得有快递100企业版账号,具体流程如下:
-
访问快递100开放平台注册企业账号。
-
在企业管理后台获取三个关键参数:
● 授权key:API调用标识
● secret:签名验证密钥(需妥善保管,避免泄露)
● siid:云打印机设备码(使用云打印时必填,本地打印可忽略)
-
在企业管理后台根据业务需求选择套餐(新用户有100单免费调试额度)。
2. 核心接口文档梳理
重点关注电子面单下单接口(接口地址:api.kuaidi100.com/label/order… 该接口支持POST/GET请求,返回JSON格式数据,核心特性如下:
● 支持三种打印模式:云打印(CLOUD)、图片打印(IMAGE)、HTML打印(HTML)
● 可生成主单+子单(最多支持1主2子)
● 自动返回快递单号、面单图片链接、大头笔等关键信息
3. 签名生成规则
为保证接口安全,所有请求必须携带签名(sign),生成逻辑如下:
-
按param + t + key + secret的顺序拼接字符串(无"+"号)
-
对拼接后的字符串进行MD5加密,转为32位大写格式
其中:
● param:业务参数的JSON字符串
● t:当前时间戳(毫秒级)
示例代码(Java):
String paramJson = "{"kuaidicom":"zhongtong","sendManName":"张三"...}";
String t = System.currentTimeMillis() + "";
String signStr = paramJson + t + key + secret;
String sign = DigestUtils.md5Hex(signStr).toUpperCase();
三、核心实现步骤(附代码示例)
1. 构造请求参数
请求参数分为公共参数和业务参数,以下是关键字段说明:
| 参数类型 | 字段名 | 必填 | 说明 |
|---|---|---|---|
| 公共参数 | key | 是 | API调用密钥 |
| 公共参数 | sign | 是 | 签名字符串 |
| 公共参数 | t | 是 | 时间戳 |
| 业务参数 | kuaidicom | 是 | 快递公司编码(如"zhongtong"代表中通) |
| 业务参数 | sendManName | 是 | 寄件人姓名 |
| 业务参数 | sendManMobile | 是 | 寄件人手机号 |
| 业务参数 | sendManPrintAddr | 是 | 寄件人打印地址 |
| 业务参数 | recManName | 是 | 收件人姓名 |
| 业务参数 | recManMobile | 是 | 收件人手机号 |
| 业务参数 | recManPrintAddr | 是 | 收件人打印地址 |
| 业务参数 | printType | 是 | 打印类型:CLOUD/IMAGE/HTML |
| 业务参数 | siid | 否 | 云打印机设备码(printType为CLOUD时必填) |
业务参数JSON示例:
{
"sendMan": {
"name": "张三",
"mobile": "15999566666",
"printAddr": "广东省深圳市南山区科技南十二路"
},
"printType": "IMAGE",
"kuaidicom": "zhaijisong",
"count": 1,
"remark": "测试下单,请勿发货",
"tempId": "636243be3ddab0001307d491",
"recMan": {
"name": "李四",
"mobile": "13888888888",
"printAddr": "北京市海淀区中关村大街1号"
}
}
2. 接口调用实现
Java版本示例(使用HttpClient)
package com.kuaidi100.api.elec.pirnt.facade.controller;
import com.google.common.collect.Maps;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class Kuaidi100LabelApi {
// 替换为自己的key和secret
private static final String KEY = "hFBwtSji7088";
private static final String SECRET = "e42beece3c01484a8ae82bcd042fe1fa";
private static final String API_URL = "http://api.kuaidi100.com/label/order";
public static void main(String[] args) throws Exception {
// 1. 构造业务参数
JSONObject param = packageParam();
// 2. 生成签名
String t = System.currentTimeMillis() + "";
String signStr = param.toString() + t + KEY + SECRET;
String sign = org.apache.commons.codec.digest.DigestUtils.md5Hex(signStr).toUpperCase();
// 3. 构造请求体
JSONObject requestBody = new JSONObject();
requestBody.put("key", KEY);
requestBody.put("sign", sign);
requestBody.put("t", t);
requestBody.put("param", param);
requestBody.put("method", "order");
// 4. 发送请求
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 构造带参数的GET请求URL
String urlWithParams = API_URL + "?method=order&key=" + KEY + "&sign=" + sign + "&t=" + t + "¶m=" + java.net.URLEncoder.encode(param.toString(), "UTF-8");
// 使用HttpGet替代HttpPost
HttpGet httpGet = new HttpGet(urlWithParams);
httpGet.setHeader("Content-Type", "application/json;charset=UTF-8");
// 执行请求并处理响应
org.apache.http.HttpResponse response = httpClient.execute(httpGet);
String result = org.apache.http.util.EntityUtils.toString(response.getEntity());
System.out.println("接口响应:" + result);
parseResponse(result);
}
}
private static JSONObject packageParam() {
JSONObject param = new JSONObject();
param.put("kuaidicom", "zhaijisong");
/*寄件人信息*/
Map<String, String> sendManInfo = Maps.newHashMapWithExpectedSize(3);
sendManInfo.put("name", "张三");
sendManInfo.put("mobile", "15999566666");
sendManInfo.put("printAddr", "广东省深圳市南山区科技南十二路");
param.put("sendMan", sendManInfo);
/*收件人信息*/
Map<String, String> recManInfo = Maps.newHashMapWithExpectedSize(3);
recManInfo.put("name", "李四");
recManInfo.put("mobile", "13888888888");
recManInfo.put("printAddr", "北京市海淀区中关村大街1号");
param.put("recMan", recManInfo);
//打印数量
param.put("count", 1);
//打印类型
param.put("printType", "IMAGE");
//备注信息
param.put("remark", "测试下单,请勿发货");
//模版id
param.put("tempId", "636243be3ddab0001307d491");
return param;
}
// 解析响应结果
private static void parseResponse(String result) {
JSONObject respJson = JSONObject.parseObject(result);
if (respJson.getBoolean("success") && respJson.getInteger("code") == 200) {
JSONObject data = respJson.getJSONObject("data");
String kuaidinum = data.getString("kuaidinum");
String labelUrl = data.getString("label");
System.out.println("快递单号:" + kuaidinum);
System.out.println("面单图片链接:" + labelUrl);
// 后续可调用打印逻辑
} else {
System.err.println("接口调用失败:" + respJson.getString("message"));
}
}
}
PHP版本示例
class Kuaidi100LabelApi {
private $key = "your_api_key";
private $secret = "your_api_secret";
private $apiUrl = "https://api.kuaidi100.com/label/order?method=order";
public function createLabel() {
// 1. 构造业务参数
$param = [
'kuaidicom' => 'zhaijisong',
'recMan' => array (
'name' => '李四', // 收件人姓名
'mobile' => '13888888888', // 收件人的手机号,手机号和电话号二者其一必填
'printAddr' => '北京市海淀区中关村大街1号' // 收件人地址
),
'sendMan' => array (
'name' => '张三', // 寄件人姓名
'mobile' => '15999566666', // 寄件人的手机号,手机号和电话号二者其一必填
'printAddr' => '广东省深圳市南山区科技南十二路' // 寄件人地址
),
'count' => 1,
'printType' => 'IMAGE',
'remark' => '测试下单,请勿发货',
'tempId' => '636243be3ddab0001307d491'
];
$paramJson = json_encode($param);
// 2. 生成签名
$t = time() * 1000;
$signStr = $paramJson . $t . $this->key . $this->secret;
$sign = strtoupper(md5($signStr));
//3、封装请求参数
$post_data = array();
$post_data['param'] = $paramJson;
$post_data['key'] = $key;
$post_data['t'] = $t;
$post_data['sign'] = $sign;
echo '请求参数:<br/><pre>';
echo print_r($post_data);
echo '</pre>';
// 3. 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->apiUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
// 4. 解析响应
$this->parseResponse($result);
}
private function parseResponse($result) {
$resp = json_decode($result, true);
if ($resp['success'] && $resp['code'] == 200) {
echo "快递单号:" . $resp['data']['kuaidinum'] . PHP_EOL;
echo "面单图片链接:" . $resp['data']['label'] . PHP_EOL;
} else {
echo "调用失败:" . $resp['message'] . PHP_EOL;
}
}
}
// 调用示例
$api = new Kuaidi100LabelApi();
$api->createLabel();
3. 打印功能实现
根据printType的不同,打印实现方式有所区别:
方案1:云打印(CLOUD)
适用于使用快递100云打印机的场景,无需本地处理打印逻辑:
-
确保siid参数正确(云打印机设备码)
-
接口调用成功后,云打印机将自动接收打印任务并执行
-
支持批量打印和多设备管理,适合多门店、多分公司场景
方案2:本地打印(IMAGE/HTML)
适用于使用自有打印机的场景:
-
从响应的label字段获取面单图片或HTML短链
-
下载图片到本地(图片格式支持PNG/JPG)
-
调用本地打印机服务执行打印,关键是配置正确的纸张尺寸:
● 常用电子面单尺寸为100mm*180mm
● 通过settings参数的pageWidth和pageHeight指定尺寸
Java本地打印示例(打印图片):
// 下载面单图片
URL url = new URL(labelUrl);
BufferedImage image = ImageIO.read(url);
// 获取本地打印机
PrinterJob printerJob = PrinterJob.getPrinterJob();
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
// 设置纸张尺寸(100mm转像素:100*3.78=378像素)
MediaPrintableArea area = new MediaPrintableArea(0, 0, 378, 680, MediaPrintableArea.PIXEL);
attributes.add(area);
// 执行打印
printerJob.setPrintable((graphics, pageFormat, pageIndex) -> {
if (pageIndex > 0) return Printable.NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) graphics;
g2d.drawImage(image, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableHeight(), null);
return Printable.PAGE_EXISTS;
});
if (printerJob.printDialog(attributes)) {
printerJob.print(attributes);
}
4. 单号回传与订单关联
打单成功后,务必将接口返回的kuaidinum(快递单号)回传到自身业务系统:
● 与商城/ERP的订单号建立关联,避免人工录入错误
● 为后续的物流轨迹查询和异常预警奠定基础
● 可通过定时任务或消息队列实现异步回传,保证系统稳定性
四、常见问题与解决方案
1. 签名错误(sign无效)
a. 检查参数拼接顺序是否严格遵循param + t + key + secret
b. 确认param是未格式化的JSON字符串(无空格、换行)
c. 验证secret是否为企业管理后台的正确密钥(非key)
2. 面单尺寸显示异常
a. 本地打印时,在打印机设置中匹配纸张实际尺寸
b. 通过接口settings参数指定pageWidth: 100(mm),pageHeight: null
c. 调整打印方向:添加direction: 1参数实现反向打印
3. 需要复打面单
a. 云打印可调用复打接口,2天内支持10次复打
b. 图片/HTML打印可保存原始链接,30天内可重复下载打印(注意单号回收机制)
4. 地址无法识别行政区
a. 参考国家统计局行政区划规则优化地址格式
b. 启用快递100智能地址解析服务,自动补全区域编码
五、拓展功能:打造全链路物流系统
快递100电子面单API可与其他接口联动,实现更完整的物流解决方案:
1. 物流轨迹订阅:在面单下单时通过op参数开启订阅,物流状态更新时自动推送至回调地址
2. 智能地址解析:精准识别数据中的姓名、电话、地址等信息。规范解析省、市、区、详细地址以及最新的国家行政区划编码。智能纠正错误地址、补全不完整地址。帮助快递或电商企业提升处理效率,减少录入失误。
3. 智能时效预估:AI+Data能力带来时效服务升级,包含全程及在途时效预估。发货前,根据收寄件地址预测不同快递公司的预计送达时间;发货后,基于快递100自研AI时效预估模型,预测快递的送达时间及途径路线,结合物流轨迹及路线节点信息动态更新,预计到达时间越临近目的地越精准。
4. 物流拦截改址:支持对“在运输途中、尚未签收”的快件进行售后服务。当用户选择退款或更改地址时,平台和商家能自动确认订单状态,在线发起拦截或改址等请求直连快递公司。
六、总结
通过快递100电子面单打印API对接,开发者可在15分钟内完成从参数配置到打印落地的全流程开发,相比传统对接方式节省80%以上的时间成本。其统一的接口规范、丰富的功能适配和完善的技术支持,让物流系统集成变得简单高效。
如果你正在开发电商商城、ERP或仓储管理系统,不妨试试这套API方案。如果在对接过程中遇到问题,欢迎在评论区交流,也可以参考快递100开放平台的官方文档、官方demo获取最新信息。
进一步探索:
希望本文对您有所帮助,欢迎在评论区交流讨论!