# 跑腿

# B 端 SaaS 统一接入文档

# 1. 接入须知

# 1.1 约定

类别 描述
坐标系 腾讯侧使用的经纬度坐标一律为国标(腾讯地图默认坐标)
城市编码 GB/T 2260,WebService API | 腾讯位置服务 (opens new window)
距离 使用 作为统一单位
费用 使用 作为单位

# 1.2 确认项

  • 创单后金额是否固定不可变更,是否需要创单金额和完单金额保证一致

  • 取消订单是否会重试,重试次数、间隔分别是多少

  • 创单/取消失败后(超时、未收到响应)是否会重试创单/取消接口,如不重试在后续接收到回调初始化订单如何处理

  • 是否存在直接创单的场景,不经过询价直接创建订单

  • 询价阶段传入信息是否可作为下单直接使用,询价是否会脱敏用户信息

  • 节假日峰值[询价QPS]{.underline}为多少

  • 是否存在一段时间内集中下单&取消的场景

  • 是否有自主联调平台供联调/测试使用,or 需要人工发单

  • 完单的回调是否需要骑手位置信息

  • 取消费需要以回调接口里的金额为准(部分场景会存在骑手/服务商取消也收取消费的情况)

  • 注意,目前腾讯侧城市编码均为地级市标准城市编码,WebService API | 腾讯位置服务 (opens new window),'北京', '上海', '重庆', '天津', '香港', '澳门' 这几个直辖市的city_code为省级编码,需要适配,如北京city_code:110000,上海:310000;

  • 上线后可否全量打开入口,由腾讯侧控制实际开城节奏(双方业务可提前商议节奏)

  • 提供产品运营研发联系方式

# 2. 接口

# 2.1 通用约定

url_prefix:

测试:https://test.tai.qq.com/api/open/express/intracity/2b (opens new window)

正式**:**https://weixin.go.qq.com/api/open/express/intracity/2b (opens new window)

如非特殊约定,统一使用如下规范

类型 描述
协议 HTTPS
请求方式 Post
数据格式 JSON,请设置 Header 的 Content-Type 为 application/json
编码 UTF-8
时间戳 毫秒
日期格式 日期格式采用 GB/T 7408-2005 标准中 "YYYY-MM-DD" 格式(示例:2022-08-01),时区统一采用东八区(即北京时间)。日期时间格式采用 "YYYY-MM-DD hh:mm:ss" 格式(示例:2022-08-01 19:00:00)。Java: "yyyy-MM-dd HH:mm:ss",PHP: "Y-m-d H:i:s",Go: "2006-01-02 15:04:05",Python: "%Y-%m-%d %H:%M:%S"

# 请求Body通用字段

名称 类型 描述 必须
seq_id string(36) 请求流水号,调用方自动生成一个随机ID,建议使用uuid Yes
timestamp long(13) 请求时间,Unix Timestamp 单位毫秒 Yes
nonce string(32) 随机字符串,数字与字母组合,区分大小写 Yes
api_key string(32) 腾讯出行服务分配给服务商的应用标识 Yes
sign string(32) 签名验证参数 Yes

# 请求响应统一数据结构

名称 类型 描述 必须
code int(11) 响应码,默认 0 为成功,其他为错误 Yes
message string(64) 错误消息,code 为 0 时返回空字符串,code 为非 0 时返回具体原因 No
data object 业务响应主体,code 为 0 时返回,具体返回对象结构见下文具体 API;code 为非 0 时不返回 No

# 2.2 被调(接入方调用腾讯出行)

# 2.2.1 询价

Route: /estimatePrice

请求Body:

名称 类型 描述 必须
third_order_id string(64) 接入方业务订单号,作为预提单的id,后续下单同一个id会作为结果直接创单,有效期5分钟(需要注意这个有效期需要提前沟通) Yes
city_name string(32) 城市名称 No
city_code string(32) 城市行政区域编码,标准行政区划编码,可参见 WebService API | 腾讯位置服务 (opens new window) Yes
goods_type int(11) 物品类别,详细见附录 3.3 Yes
goods_weight float 物品重量(单位 kg) Yes
express_type int 跑腿类型,详细见枚举 Yes
order_phone varchar(64) 下单人手机号 Yes
sender_address AddressInfo 地址信息,详细结构见附录 AddressInfo Yes
receiver_address AddressInfo 地址信息,详细结构见附录 AddressInfo Yes
enable_receive_code bool 是否启用收货码 Yes
trade_order_source string 订单来源,可见订单来源枚举,未在枚举中可传入原始字符串 No
trade_order_source_sequence string 订单来源流水号 No
goods_details List<GoodsDetail> 物品明细数据 No
expected_delivery_time long 预期送达时间,时间戳,格式为 long,时区为 GMT+8,即距离 Epoch(1970年1月1日)以秒计算的时间(unix-timestamp) No
trade_order_id string 商流订单号(订单来源渠道的订单号) No

响应Body业务字段:

名称 类型 描述 必须
express_type int 跑腿类型,详细见枚举 Yes
delivery_time long 预计送达时间 No
delivery_distance int 配送距离,米 Yes
deliver_fee int 运费总价 Yes
total_fee int 实际支付金额 Yes
coupon_fee int 优惠金额 Yes

# 2.2.2 创建订单

询价和创单传递信息不一致的情况,需要提前告知,询价不作为预提单来源

Route: /createOrder

请求Body:

名称 类型 描述 必须
third_order_id string(64) 接入方业务订单号 Yes
city_name string(64) 寄件城市名称,如北京市、深圳市 Yes
city_code string(64) 寄件城市 code No
goods_type int(11) 物品类别,详细见附录 3.3 Yes
goods_weight float 物品重量(单位 kg) Yes
order_phone varchar(64) 下单人手机号 Yes
express_type int 跑腿类型,详细见枚举 Yes
sender_address AddressInfo 地址信息,详细结构见附录 AddressInfo Yes
receiver_address AddressInfo 地址信息,详细结构见附录 AddressInfo Yes
enable_receive_code boolean 启用收货码 Yes
estimate_deliver_fee int 询价结果金额(询价时腾讯返回的金额 totalFee),直接下单时不需要 No
remark string 备注(按照运力支持备注长度截取) No
callback string 回调地址,如果不需要根据订单设置不同的回调地址,可以给固定值腾讯侧配置(使用该字段,需要和腾讯侧确认) No
trade_order_source string 订单来源,可见订单来源枚举,未在枚举中可传入原始字符串 No
trade_order_source_sequence string 订单来源流水号 No
goods_details List<GoodsDetail> 订单详情数据 No
expected_delivery_time long 时间戳,格式为 long,时区为 GMT+8,即距离 Epoch(1970年1月1日)以秒计算的时间(unix-timestamp) No
trade_order_id string 商流订单号(订单来源渠道的订单号) No

响应Body业务字段:

名称 类型 描述 必须
order_code string(64) 腾讯业务订单号 Yes
express_type int 跑腿类型,详细见枚举 Yes
delivery_time long 预计送达时间 No
delivery_distance int 配送距离,米 Yes
deliver_fee int 运费总价 Yes
total_fee int 实际支付金额 Yes
coupon_fee int 优惠金额 Yes

# 2.2.3 取消订单

Route: /cancelOrder

请求Body:

名称 类型 描述 必须
order_id string(64) 订单号 Yes
order_type int(4) 查询订单ID类型,详细信息见附录 3.7 Yes
cancel_type int(4) 取消类型 No
cancel_reason string(64) 取消原因 No

响应Body业务字段:

名称 类型 描述 必须
cancel_result bool 取消结果,true: 取消成功,false: 取消失败 Yes(注意,响应 code 是代表业务响应正常,是否取消成功要根据本字段判断)
cancel_fail_reason string(64) 取消失败原因枚举,详细见附录 3.6 No
cancel_fee int 取消费 No

# 2.2.4 查询订单详情

Route: /orderDetail

请求Body:

名称 类型 描述 必须
order_id string(64) 订单号 Yes
order_type int(4) 查询订单ID类型,详细信息见附录 3.7 Yes

响应Body业务字段:

名称 类型 描述 必须
order_code string(64) 腾讯业务订单号 Yes
third_order_id string(64) 接入方业务订单号 Yes
order_status int(11) 订单状态 Yes
delivery_time int(13) 预计送达时间 No
total_fee int(11) 应付金额 Yes
pay_fee int(11) 实际支付金额 Yes
coupon_fee int(11) 优惠金额 No
cancel_fee int(11) 取消金额 No
sp_info SpInfo 服务商信息,详情结构见附录 SpInfo No
delivery_distance int(11) 配送距离 完单后:Yes
receive_code string(32) 收货码 Yes,打开收货码才有
rider_info RiderInfo 骑手信息 接单后:Yes
pickup_pic List<String> 取货照片 url No
complete_pic List<String> 妥投照片 url No

# 2.2.5 查询骑手信息(位置)

Route: /riderLocation

请求Body:

名称 类型 描述 必须
order_id string(64) 订单号 Yes
order_type int(4) 查询订单ID类型,详细信息见附录 3.7 Yes

响应Body业务字段:

名称 类型 描述 必须
data RiderLocationInfo 骑手信息 Yes

# 2.2.6 查询订单状态变更节点(可选)

Route: /orderStatusChangeNode

请求Body:

名称 类型 描述 必须
order_id string(64) 订单号 Yes
order_type int(4) 查询订单ID类型,详细信息见附录 3.7 Yes

响应Body业务字段:

名称 类型 描述 必须
data List<OrderStatusChangeNode> 订单状态变更节点,按变更时间正序排序,详细信息见下方对象实体表 Yes

# 2.2.7 二次确认(暂时不支持)

骑手接单后需要指定窗口内调用确认选单,否则超时将自动取消订单

# 2.3 主调(腾讯调用接入方同步订单状态)

接入方提供Host

# 2.3.1 订单状态同步

Route: /status

请求Body:

名称 类型 描述 必须
order_code string(64) 腾讯业务订单号 Yes
third_order_id string(64) 接入方业务订单号 Yes
sp_info SpInfo 实际运力信息,详情结构见附录 SpInfo No
event int(11) 事件类型,见下文事件类型 Yes
status int(11) 订单状态 Yes
fee_info FeeInfo 费用信息 Yes(接单后)
accepted_info AcceptedInfo 已接单事件相关信息 根据具体状态填充
reassign_info ReassignInfo 骑手转单事件相关信息 根据具体状态填充
arrived_info ArrivedInfo 已到达取件点事件相关信息 根据具体状态填充
delivering_info DeliveringInfo 骑士出发开启送货事件相关信息 根据具体状态填充
send_back_info SendBackInfo 送回物品事件相关信息 根据具体状态填充
cancel_info CancelInfo 取消事件相关 根据具体状态填充
completed_info CompletedInfo 完成事件相关 根据具体状态填充

响应Body业务字段:

名称 类型 描述 必须
accept_time int(13) 通知接收处理时间 Yes

# 3. 附录

# 3.1 对象实体表

AddressInfo

名称 类型 描述 必须
name string(32) 姓名/昵称 Yes
phone string(32) 手机,传入真实手机号 Yes
address_detail string(64) 详细地址 No,与 poi_address 中必须传递一个
poi_address string(64) poi 地址信息 No,与 address_detail 中必须传递一个
poi_title string(64) poi 标题 Yes
poi_lng double 经度 Yes
poi_lat double 纬度 Yes

SpInfo

名称 类型 描述 必须
sp_name string(64) 服务商名称 Yes
sp_code string(64) 服务商唯一标识 Yes

RiderInfo

名称 类型 描述 必须
name string(32) 名称 Yes
phone_type int(11) 1-AXN/真实号,2-AXB Yes
phone string(32) 手机号(真实号或AXN的虚拟号),phone_type=1 时有值 No
phones List<PhoneInfo> 下单人,发货人,收货人对应关系,phoneType=2 时有值 No

PhoneInfo

名称 类型 描述 必须
role_type int(11) 角色(1-下单人,2-收货人,3-发货人),下单人手机号以注册手机号为准 Yes
virtual_phone string(32) 虚拟手机号 Yes

RiderLocationInfo

名称 类型 描述 必须
rider_lng double 骑手经度 Yes
rider_lat double 骑手纬度 Yes

EstimateTimeInfo

名称 类型 描述 必须
accept_time int(13) 预计骑手接单时间 根据订单状态决定
depart_pick_time int(13) 预计出发时间 根据订单状态决定
arrive_pickup_point_time int(13) 预计取件时间 根据订单状态决定
finish_time int(13) 预计送达时间 根据订单状态决定
send_back_finish_time int(13) 送回预计送达时间 根据订单状态决定

CancelInfo

名称 类型 描述 必须
timestamp long 取消时间,Unix Timestamp 单位毫秒 Yes
reason_id int(11) 取消原因 Id Yes
reason_desc string(64) 取消原因 No
cancel_from int(11) 取消来源,1: 用户,2: 接入方系统取消 Yes
cancel_fee int(11) 取消费 No

ExceptionInfo

名称 类型 描述 必须
timestamp long 异常产生时间,Unix Timestamp 单位毫秒 Yes
exception_id int(11) 取消编码 Yes
exception_desc string(64) 取消原因 No

CancelRule

名称 类型 描述 必须
name string(64) 规则名称 Yes
start int(11) 开始时间 Yes
end int(11) 截止时间 Yes
fee int(11) 费用 Yes

OrderStatusChangeNode

名称 类型 描述 必须
order_status int(11) 订单状态 Yes
event int(11) 事件类型,见下文事件类型 Yes
order_change_time long 订单状态变更时间戳,单位: 毫秒 Yes

GoodsDetail

名称 类型 描述 必须
name string 货品名称
count int 货品数量
price double 货品价值,选填,数值不小于0,精确到小数点后两位(如果小数点后位数多于两位,则四舍五入保留两位小数)
unit string 货品单位

FeeInfo

名称 类型 描述 必须
total_fee int(11) 应付金额 Yes
pay_fee int(11) 实际支付金额(total_fee - coupon_fee) Yes
coupon_fee int(11) 优惠金额 No
cancel_fee int(11) 取消金额 No

回调相关数据结构

AcceptedInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
estimate_time_info EstimateTimeInfo 预估时间信息 No
rider_info RiderInfo 骑手信息 Yes
send_code string(32) 发货码 No
receive_code string(32) 收货码 Yes
rider_location_info RiderLocationInfo 骑手位置信息 Yes

ReassignInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
reassign_type int(11) 转单原因类型,1-骑手转单,2-服务商转单 Yes
estimate_time_info EstimateTimeInfo 新预估时间信息 No
rider_info RiderInfo 新骑手信息 Yes
rider_location_info RiderLocationInfo 骑手位置信息 Yes

ArrivedInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
estimate_time_info EstimateTimeInfo 新预估时间信息 No
rider_location_info RiderLocationInfo 骑手位置信息 Yes
rider_info RiderInfo 骑手信息 Yes

DeliveringInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
estimate_time_info EstimateTimeInfo 新预估时间信息 No
pickup_pic List<String> 取件照片 url,回调的照片 url 为未经过风控及压缩图片且存在过期可能【慎用】 No
rider_location_info RiderLocationInfo 骑手位置信息 Yes
rider_info RiderInfo 骑手信息 Yes

CompletedInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
rider_location_info RiderLocationInfo 骑手位置信息 Yes
complete_pic List<String> 妥投照片 url,回调的照片 url 为未经过风控及压缩图片且存在过期可能【慎用】 No
rider_info RiderInfo 骑手信息 Yes

SendBackInfo

名称 类型 描述 必须
timestamp long 事件发生时间点,Unix Timestamp 单位毫秒 Yes
estimate_time_info EstimateTimeInfo 新预估时间信息 No
rider_location_info RiderLocationInfo 骑手位置信息 Yes
rider_info RiderInfo 骑手信息 Yes

# 3.2 订单状态表:供参考

状态编码 名称 描述 支付/退款状态说明
30050 DISPATCHING 派单中 已支付
30100 PICKING 取件中 已支付
30200 ARRIVED_PICK_POINT 到达取件点 已支付
30300 DELIVERING 送件中 已支付
30400 SENDING_BACK 送回中 已支付
30700 CANCELING 取消中 已支付未退款
30710 CANCELED 已取消 已退款
30900 ARRIVED 已送达 已支付
事件编码 名称 描述 必须
150 DISPATCH 派单/改派 Yes
200 RIDER_ACCEPT 骑手接单 Yes
250 RIDER_REASSIGN 骑手转单 Yes: 有转单,No: 无转单
300 ARRIVE_PICK_POINT 到达取件点 Yes
400 DEPART_SEND 开始送件 Yes
450 ARRIVED 已送达 Yes
500 RIDER_SEND_BACK 骑手送回 Yes: 有送回,No: 无送回
670 SP_REASSIGN 运力骑手改派(回到派单中) Yes: 有改派,No: 无改派
950 CANCEL 取消,内部可能需要区分具体取消原因 Yes: 有取消,No: 无取消
960 REFUND 退款通知 Yes: 有退款,No: 无退款

# 3.3 物品类型表

id 类型
1 文件证照
2 服饰
3 食品饮料
4 蛋糕
5 鲜花
6 数码
7 水果生鲜
8 药品
9 汽配
10 个护美妆
11 家居家纺
12 其他

# 3.4 跑腿类型

id 类型
1 特惠拼送
2 极速直送

# 3.5 订单来源

id 类型
10 美团
20 饿了么
30 抖音
40 京东外卖
50 淘宝闪购
60 歪马微商城
70 有赞云

# 3.6 取消原因表--用户

id 父类别 子类别 类型
1 和自己有关 填写的取件/收件信息有误 单选
2 计划有变,暂时不需要寄件 单选
3 和平台有关 没有骑手接单 单选
4 派的骑手距离太远 单选
5 和骑手有关 联系不上骑手 单选
6 骑手要求我取消订单 单选
7 骑手行驶过于缓慢或长时间不移动 单选
20 其他 其他 输入框

# 3.6.1 取消失败原因表

取消失败原因
当前订单状态不支持
服务商侧取消失败
其它

# 3.7 查询订单ID类型表

id 订单类型
1 腾讯业务订单号
2 接入方业务订单号

# 3.8 腾讯错误码

code message 说明
0 success
400000 请求参数错误,备注超长
400001 请求URL错误
400002 请求方法错误
400003 appId错误
400004 时间戳过期或者nonce重复
400005 签名验证失败
400101 请求频繁,请稍后重试
400102 询价价格已失效,请重新询价
400103 询价地址不支持
400100 通用非影响主流程错误码,无需关注的业务错误码
400201 渠道方订单状态不匹配
500000 其他系统错误,需要接入方以一定策略进行重试,建议指数递增重试:需要在1s,2s,4s,8s,16s,32s,64s进行重试,且最后一次重试应当在第一次重试1min以上

# 3.9 签名算法

# 3.9.1 描述

  1. 从请求串中获得 api_key、seq_id、timestamp, nonce 通用字段以及其他的业务段和鉴权结果字段 sign。

  2. 根据签名算法,对参与签名的内容进行签名; 按照除 sign 外参数名称排序(字典升序排列)成"key1=value1&key2=value2&...."的原始字符串 src1;请求报文中不存在的参数不参与签名。 将原始字符串+分配给调用方的 api_sercret 形成字符串 src2; 将 src2 进行 md5 后转成大写形成签名内容 dest

  3. 将步骤 2 中得到的签名内容 dest 与请求中的 sign 字段内容做比较,如果相同则验证成功,否
    则判定请求非法。举例: 假设注册接口文档中业务字段为[name, phone,address],分配的 api_sercret= DZaslH9B9ycqRrE77laCPB2Om, 请求参数如下: api_key=PSUBZLHOKUO6HV52A5CAUSSE5KSB6Y, seq_id=b8b4f0b8-01fb-4c06-80b9-3ab895a8c616, timestamp=1726214265, nonce=123456,name=test, phone=11111111111,address=北京市朝阳区亚洲金融大厦 则需要签名的内容:

address=北京市朝阳区亚洲金融大厦&api_key=PSUBZLHOKUO6HV52A5CAUSSE5KSB6Y&name=test&nonce=e2fa80izRF&phone=11111111111&seq_id=b8b4f0b8-01fb-4c06-80b9-3ab895a8c616&timestamp=1726214265DZaslH9B9ycqRrE77laCPB2Om

  1. 计算的 MD5 值为 afc4a5b550c1f5c92bca917aba66faf5,大写值为

AFC4A5B550C1F5C92BCA917ABA66FAF5

  1. 将步骤 4 中得到的 MD5 值,与请求中 sign 字段的值比较。两者相同请求合法

注意:签名时对对象类型的value需进行json序列化后的字符串拼接,这里的json需与主调HTTP客户端传输的json保持key顺序一致,验签时会原样提取json中的value

# 3.9.2 示例

# Java

算法工具类

用例

# Golang