快递电子面单接口API比较常用在电商、仓储系统和ERP系统,对接后不用下载安装软件,可以直接嵌入系统网站调用。
目前有快递鸟和菜鸟提供集成的电子面单打印接口,分别支持20,15家快递的电子面单打印
1.1 接口
(1)、订单编号(OrderCode)不可重复提交,重复提交系统会返回具体错误代码。
(2)、支持常用20家快递电子面单打印。
(3)、测试地址:http://testapi.kdniao.cc:8081/api/eorderservice/
(4)、正式地址:http://api.kdniao.cc/api/EOrderService
(5)、接口申请:快递鸟网站注册账号申请接口
(6)、单号申请:部分快递需提前申请单号
1.2 系统级和应用级输入参数
系统级输入参数 | 应用级输入参数 | 类型 | 是否必须 | 描述 | ||
RequestData(必填参数,请求内容,JSON格式,须和DataType一致) | CallBack | String | O | 用户自定义回调信息 | ||
MemberID | String | O | 会员标识 平台方与快递鸟统一用户标识的商家ID | |||
CustomerName | String | O | 电子面单客户账号 (与快递网点申请或通过快递鸟官网申请或通过申请电子面单客户号申请) | |||
CustomerPwd | String | O | 电子面单密码 | |||
SendSite | String | O | 收件网点标识 | |||
ShipperCode | String | R | 快递公司编码 | |||
LogisticCode | String | O | 快递单号 | |||
ThrOrderCode | String | O | 第三方订单号 | |||
OrderCode | String | R | 订单编号 | |||
MonthCode | String | C | 月结编码 | |||
PayType | Int | R | 邮费支付方式: 1-现付,2-到付,3-月结,4-第三方支付 | |||
ExpType | String | R | 快递类型:1-标准快件 | |||
IsNotice | Int | O | 是否通知快递员上门揽件:0-通知;1-不通知;不填则默认为1 | |||
Cost | Double | O | 寄件费(运费) | |||
OtherCost | Double | O | 其他费用 | |||
Receiver | Company | String | O | 收件人公司 | ||
Name | String | R | 收件人 | |||
Tel | String | R | 电话与手机,必填一个 | |||
Mobile | String | |||||
PostCode | String | O | 收件人邮编 | |||
ProvinceName | String | R | 收件省(如广东省,不要缺少“省”) | |||
CityName | String | R | 收件市(如深圳市,不要缺少“市”) | |||
ExpAreaName | String | O | 收件区(如福田区,不要缺少“区”或“县”) | |||
Address | String | R | 收件人详细地址 | |||
Sender | Company | String | O | 发件人公司 | ||
Name | String | R | 发件人 | |||
Tel | String | R | 电话与手机,必填一个 | |||
Mobile | String | |||||
| PostCode | String | O | 发件人邮编 | ||
ProvinceName | String | R | 发件省(如广东省,不要缺少“省”) | |||
CityName | String | R | 发件市(如深圳市,不要缺少“市”) | |||
ExpAreaName | String | O | 发件区(如福田区,不要缺少“区”或“县”) | |||
Address | String | R | 发件详细地址 | |||
StartDate | String | O | 上门取货时间段: "yyyy-MM-dd HH:mm:ss"格式化,本文中所有时间格式相同 | |||
EndDate | String | O | ||||
Weight | Double | O | 物品总重量kg | |||
Quantity | Int | O | 件数/包裹数 | |||
Volume | Double | O | 物品总体积m3 | |||
Remark | String | O | 备注 | |||
AddService | Name | String | 0 | 增值服务名称 | ||
Value | String | 0 | 增值服务值 | |||
CustomerID | String | 0 | 客户标识(选填) | |||
Commodity | GoodsName | String | R | 商品名称 | ||
GoodsCode | String | O | 商品编码 | |||
Goodsquantity | Int | O | 件数 | |||
GoodsPrice | Double | O | 商品价格 | |||
GoodsWeight | Double | O | 商品重量kg | |||
GoodsDesc | String | O | 商品描述 | |||
GoodsVol | Double | O | 商品体积m3 | |||
IsReturnPrintTemplate | String | O | 返回电子面单模板: 0-不需要;1-需要 | |||
| IsSendMessage | Int | O | 是否订阅短信 0-不需要;1-需要 | ||
| TemplateSize | String | O | 模板尺寸 | ||
EBusinessID |
| String | R | 商户ID | ||
RequestType | String | R | 请求指令类型:1007 | |||
DataSign | String | R | 数据内容签名 | |||
DataType | String | R | 请求、返回数据类型: 2-json | |||
| | | | | | |
1.3 返回结果参数
l 同步返回
参数名称 | 类型 | 必须要求 | 说明 | |
EBusinessID | String | R | 电商用户ID | |
Order | OrderCode | String | R | 订单编号 |
ShipperCode | String | R | 快递公司编码 | |
LogisticCode | String | R | 快递单号 | |
MarkDestination | String | O | 大头笔 | |
OriginCode | String | O | 始发地区域编码 | |
OriginName | String | O | 始发地/始发网点 | |
DestinatioCode | String | O | 目的地区域编码 | |
DestinatioName | String | O | 目的地/到达网点 | |
SortingCode | String | O | 分拣编码 | |
PackageCode | String | O | 集包编码 | |
Success | Bool | R | 成功与否 | |
ResultCode | String | R | 错误编码 | |
Reason | String | O | 失败原因 | |
UniquerRequestNumber | String | R | 唯一标识 | |
PrintTemplate | String | O | 面单打印模板 | |
EstimatedDeliveryTime | String | O | 订单预计到货时间yyyy-mm-dd | |
Callback | String | O | 用户自定义回调信息 | |
SubCount | Int | O | 子单数量 | |
SubOrders | String | O | 子单号 | |
SubPrintTemplates | String | O | 子单模板 | |
ReceiverSafePhone | String | O | 收件人安全电话 | |
SenderSafePhone | String | 0 | 寄件人安全电话 | |
DialPage | String | R | 拨号页面网址(转换成二维码可扫描拨号) |
2 批量打印接口对接demo
package cc.kdniao.api;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.internal.messaging.saaj.util.Base64;
/**
* Servlet implementation class printOrder
*/
@WebServlet("/printOrder")
public class printOrder extends HttpServlet {
private static final long serialVersionUID = 1L;
final String EBussinessID = "";//kdniao.com EBusinessID
final String AppKey = ""; //kdniao.com AppKey
final Integer IsPreview = 0; //是否预览 0-不预览 1-预览
/**
* @see HttpServlet#HttpServlet()
*/
public printOrder() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
PrintWriter print = response.getWriter();
String jsonResult = "";
try {
String ip = getIpAddress(request);
jsonResult = getPrintParam(ip);
} catch (Exception e) {
//write log
}
print.println(jsonResult);
print.flush();
print.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, UnsupportedEncodingException {
// TODO Auto-generated method stub
response.setContentType("");
PrintWriter print = response.getWriter();
String jsonResult = "";
try {
String ip = getIpAddress(request);
jsonResult = getPrintParam(ip);
} catch (Exception e) {
//wirte log
}
print.println(jsonResult);
print.flush();
print.close();
}
/**
* get print order param to json string
* @return
*
* @throws Exception
*/
private String getPrintParam(String ip) throws Exception {
String data = "[{\"OrderCode\":\"234351215333113311353\",\"PortName\":\"SF\"},{\"OrderCode\":\"234351215333113311354\",\"PortName\":\"打印机名称二\"}]";
String result = "{\"RequestData\": \"" + URLEncoder.encode(data, "UTF-8") + "\", \"EBusinessID\":\"" + EBussinessID + "\", \"DataSign\":\"" + encrpy(ip + data, AppKey) + "\", \"IsPreview\":\""
+ IsPreview + "\"}";
return result;
}
private String md5(String str, String charset) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(charset));
byte[] result = md.digest();
StringBuffer sb = new StringBuffer(32);
for (int i = 0; i < result.length; i++) {
int val = result[i] & 0xff;
if (val <= 0xf) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
return sb.toString().toLowerCase();
}
private String encrpy(String content, String key) throws UnsupportedEncodingException, Exception {
String charset = "UTF-8";
return new String(Base64.encode(md5(content + key, charset).getBytes(charset)));
}
/**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public final static String getIpAddress(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
}
}