一、整体对接流程(先搞清楚全链路)⭐
服务器对接快递鸟(电子面单/下单)的标准流程:
1️⃣ 客户端下单(订单信息)
2️⃣ 服务器校验业务数据(地址、商品、快递公司)
3️⃣ 服务器调用快递鸟「下单接口」
4️⃣ 快递鸟返回:
- 运单号
- 面单数据(电子面单)
5️⃣ 服务器将面单信息存数据库
6️⃣ 返回运单号 / 面单给前端
7️⃣ 后续:打印面单 / 查询物流轨迹
⚠️ 所有快递鸟接口只能由服务器调用,不能前端直调
二、快递鸟核心信息准备
你需要先在快递鸟后台获取:
text
EBusinessID # 商户ID
ApiKey # API密钥
ReqURL # 接口地址(测试/正式)
三、快递鸟:下单(电子面单)接口说明
接口类型
1007:电子面单下单接口
请求方式
- POST
- application/x-www-form-urlencoded
四、服务器请求示例(Python 版)
1️⃣ 请求参数结构
python
import json
import hashlib
import base64
import requests
from urllib.parse import quote
EBusinessID = "你的EBusinessID"
ApiKey = "你的ApiKey"
ReqURL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"
2️⃣ 构造 RequestData(重点)
python
request_data = {
"OrderCode": "ORDER_10001",
"ShipperCode": "SF", # 顺丰
"PayType": 1,
"ExpType": 1,
"Receiver": {
"Name": "张三",
"Mobile": "13800000000",
"ProvinceName": "广东省",
"CityName": "深圳市",
"ExpAreaName": "南山区",
"Address": "科技园xxx"
},
"Sender": {
"Name": "李四",
"Mobile": "13900000000",
"ProvinceName": "广东省",
"CityName": "深圳市",
"ExpAreaName": "福田区",
"Address": "公司地址"
},
"Commodity": [
{
"GoodsName": "文件"
}
]
}
3️⃣ 生成 DataSign(非常关键)
python
def generate_sign(data, api_key):
data = json.dumps(data, ensure_ascii=False)
sign = hashlib.md5((data + api_key).encode('utf-8')).digest()
return base64.b64encode(sign).decode()
4️⃣ 发送请求
python
def send_order(data):
request_data = json.dumps(data, ensure_ascii=False)
params = {
"EBusinessID": EBusinessID,
"RequestType": "1007",
"RequestData": quote(request_data),
"DataSign": generate_sign(data, ApiKey),
"DataType": "2"
}
response = requests.post(ReqURL, data=params, timeout=10)
return response.json()
5️⃣ 调用并获取返回结果
python
result = send_order(request_data)
if result.get("Success"):
order_info = result["Order"]
shipper_code = order_info["ShipperCode"]
logistic_code = order_info["LogisticCode"]
print_no = order_info.get("PrintTemplate") # 面单模板
else:
raise Exception(result.get("Reason"))
五、数据库表设计(非常重要)⭐
快递面单表(示例)
sql
CREATE TABLE shipping_label (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_code VARCHAR(64) NOT NULL,
shipper_code VARCHAR(20),
logistic_code VARCHAR(64),
receiver JSON,
sender JSON,
print_template LONGTEXT,
raw_response JSON,
created_at DATETIME,
updated_at DATETIME
);
Django Model 示例
python
class ShippingLabel(models.Model):
order_code = models.CharField(max_length=64)
shipper_code = models.CharField(max_length=20)
logistic_code = models.CharField(max_length=64)
receiver = models.JSONField()
sender = models.JSONField()
print_template = models.TextField()
raw_response = models.JSONField()
created_at = models.DateTimeField(auto_now_add=True)
六、存储面单信息(核心逻辑)
python
ShippingLabel.objects.create(
order_code=request_data["OrderCode"],
shipper_code=shipper_code,
logistic_code=logistic_code,
receiver=request_data["Receiver"],
sender=request_data["Sender"],
print_template=order_info.get("PrintTemplate"),
raw_response=result
)
七、面单打印方式(两种)
✅ 1️⃣ 前端打印(推荐)
- 后端返回
PrintTemplate - 前端用 iframe / lodop 打印
✅ 2️⃣ 后端生成 PDF
- 使用 wkhtmltopdf / reportlab
- 适合无人仓 / 自动打印
八、异常 & 幂等(非常重要 ⚠️)
❗ 同一个订单只能下单一次
python
ShippingLabel.objects.filter(order_code=order_code).exists()
避免重复调用接口!
九、安全 & 生产建议
✅ 必做:
- ApiKey 只放服务器
- 请求加超时
- 保存原始返回数据
- 失败日志落库
❌ 不要:
- 前端直调
- 忽略失败状态