在日常企业运营中,审批通过后手动下单快递是一个高频重复劳动。本文记录了如何通过钉钉开放平台,实现审批通过后自动调用中通快递 API 下单并打印电子面单的完整流程。

钉钉审批中心 — 审批流配置
📝
发起申请
👤
主管审批
审批通过
📦
自动下单
🖨
打印面单

一、整体架构设计

整个流程分为三个核心模块:

二、钉钉开放平台配置

2.1 创建企业内部应用

登录钉钉开发者后台,创建企业内部应用,获取 AppKeyAppSecret。关键步骤:

  1. 进入「应用开发」→「企业内部开发」
  2. 填写应用基本信息,开启「审批」权限
  3. 在「事件与回调」中配置回调 URL

2.2 事件订阅

我们需要监听的核心事件是 bpms_instance_change,它会在审批实例状态变更时触发。

// 审批事件回调处理
const handleApprovalEvent = async (event) => {
  const { EventType, ProcessCode, Result, BusinessId } = event;

  if (EventType === 'bpms_instance_change' && Result === 'agree') {
    // 审批通过,获取详情
    const detail = await getApprovalDetail(BusinessId);
    await createExpressOrder(detail);
  }
};

三、中通快递 API 对接

中通快递 API — 核心接口
接口方法说明
/api/order/createPOST创建快递订单
/api/waybill/getPOST获取电子面单
/api/order/traceGET物流轨迹查询
/api/order/cancelPOST取消订单

3.1 下单接口调用

const createExpressOrder = async (approvalData) => {
  const payload = {
    sender: {
      name: approvalData.senderName,
      phone: approvalData.senderPhone,
      address: approvalData.senderAddress,
    },
    receiver: {
      name: approvalData.receiverName,
      phone: approvalData.receiverPhone,
      address: approvalData.receiverAddress,
    },
    cargo: {
      name: approvalData.cargoName,
      count: approvalData.cargoCount,
      weight: approvalData.cargoWeight,
    },
    // 签名必须按文档要求生成
    sign: generateSign(payload, API_SECRET),
  };

  const res = await axios.post('https://api.zto.com/order/create', payload);
  return res.data;
};

四、关键踩坑记录

⚠️ 签名算法注意:中通 API 的签名是将所有参数按 ASCII 排序后拼接,再 MD5 加密。很多人在这里翻车是因为忽略了嵌套对象需要扁平化处理。

另一个常见问题是钉钉回调的加解密。钉钉使用 AES-128-CBC 加密,需要正确配置 EncodingAESKey,并在回调处理中先解密再解析 JSON。

五、部署与监控

生产环境使用 PM2 进行进程管理,配合 Caddy 反向代理提供 HTTPS 访问。关键配置:

# process.json
{
  "apps": [{
    "name": "dingtalk-express",
    "script": "./src/index.js",
    "instances": 2,
    "env": {
      "NODE_ENV": "production",
      "DINGTALK_APP_KEY": "your_app_key"
    }
  }]
}

六、总结

这套方案上线后,快递下单流程从人工 5 分钟/单降到全自动 3 秒/单,错误率从约 8% 降至近 0。核心经验:先理清业务数据流,再对接 API,最后处理边界情况。