10 KiB
10 KiB
物流消息推送方案(用户端 + 商家端)
日期:2026-02-11
0. 文档定位
本方案用于把“第三方快递轨迹(platform_express_*)”与移动端推送(uni-push2)结合,向:
- 用户端(C 端):推送订单物流节点更新,并在消息中心可回溯、可标记已读。
- 商家端(B 端):推送与发货/履约强相关的物流节点更新(重点关注异常/签收等),并在商家消息中心可回溯。
约束与口径继承自本目录既有文档:
- 统一事件模型、字段契约、状态映射:见接口与字段相关文档。
- 敏感信息(raw_payload、完整手机号/地址、POD 等)必须按角色授权,不得通过推送明文下发。
1. 背景与目标
1.1 背景
配送模块的事实数据源是第三方轨迹事件流:Webhook/轮询接收后入库到 platform_express_* 三表。
1.2 目标
- 及时性:当运单产生关键节点时,用户/商家能收到提醒。
- 一致性:推送只是“变更通知”,最终展示以平台查询接口返回的
status_history为准。 - 可追溯:所有推送对应的“物流消息”可在消息中心列表查询,并可已读/未读统计。
- 合规与隐私:推送 payload 与通知文案不包含敏感信息,不透传 raw。
1.3 不在本方案范围
- 自营骑手/同城配送任务(
ml_delivery_*)的接单/导航/送达链路。 - 厂商通道(小米/华为等)离线能力细节(可在 uni-push2 联调文档基础上扩展)。
2. 数据源与现有模型复用
2.1 事实数据表(生产口径)
platform_express_waybills:运单摘要(current_status_*、last_synced_at)。platform_express_tracking_events:轨迹事件事实表(event_time/event_text/status_code 等)。platform_express_event_raw:原始留痕与验签审计(仅运维/客服可见)。
结论:
- 消息生成以
platform_express_tracking_events的新增事件为触发。 - 通知展示以
platform_express_waybills.current_status_code/text+ 最新事件摘要为基础。
2.2 统一状态码(必须遵循)
使用平台统一 status_code:
ORDER_PLACED / SHIPPED / IN_TRANSIT / OUT_FOR_DELIVERY / READY_FOR_PICKUP / DELIVERED / EXCEPTION / RETURNED
映射规则来自“状态映射表”,平台内部应保证确定性。
3. 总体架构(事件驱动 + 推送唤醒刷新)
3.1 核心原则
- Push ≠ 数据源:Push 仅承载“发生了什么/在哪里看”,不承载完整时间线。
- App 打开详情页时以接口/DB查询为准:避免推送丢失、乱序导致前端状态不一致。
3.2 推荐链路
- 第三方回调/轮询到达平台(Webhook handler / polling job)
- 平台:验签、防重放、幂等去重、乱序入库
- 平台:基于“新插入事件”计算是否需要生成物流消息(对 C/B 端分别判断)
- 平台:写入“物流消息表”(用于消息中心/未读)
- 平台:按收件人设备 CID 列表调用 uni-push2 发送通知/透传
- 客户端:收到推送 -> 更新消息中心未读角标/缓存 -> 用户点击进入订单/物流详情 -> 拉取最新时间线
4. 推送场景清单(C 端 + B 端)
4.1 场景分级(建议最小可用)
为了避免 IN_TRANSIT 等高频节点造成骚扰,MVP 建议:
- 只对“状态级别变化”或“关键状态”推送,并允许后续配置化扩展。
4.2 用户端(C 端)推送场景
对单个订单/运单,建议推送:
SHIPPED:商家已发货/已绑定运单OUT_FOR_DELIVERY:派送中READY_FOR_PICKUP:待取件DELIVERED:已签收EXCEPTION:异常(破损/拒收/地址不详等)RETURNED:退回/退件
可选(非必须、后续再做):
IN_TRANSIT:仅在“跨天/关键节点”或“长时间无更新后恢复更新”时推送。
4.3 商家端(B 端)推送场景
商家端更关注履约风险与闭环结果,建议推送:
SHIPPED:发货成功(用于确认运单绑定成功/进入履约)DELIVERED:已签收(用于完成售后风险关闭)EXCEPTION:异常(优先级最高)RETURNED:退回/退件
可选(按业务需要):
OUT_FOR_DELIVERY:派送中(对高价值订单可能有意义)
4.4 同一事件对不同端的文案差异
- 同一事件事实字段同源(event_time/event_text/status_code)。
- C 端文案可更贴近用户体验(避免网点内部信息、避免电话明文)。
- B 端文案以进度/风险为主(异常/退回明确提示)。
5. 消息生成规则(幂等 + 去噪)
5.1 生成触发点
在平台完成 platform_express_tracking_events 插入成功后触发(建议异步队列/任务)。
5.2 幂等与去重
事件表已有 (waybill_id, dedupe_key) 唯一约束;消息层建议再做一层幂等:
- 推荐幂等键:
recipient_scope + recipient_id + waybill_id + status_code + event_time - 若第三方提供
event_id,可用:recipient_scope + recipient_id + waybill_id + event_id
保证:同一条事件重试/重复推送不会造成消息中心重复。
5.3 去噪(MVP)
- 默认仅对 4.2/4.3 列出的状态集合生成消息。
- 同状态多事件:只推“最新 event_time”对应的一条(或按节点去重)。
6. Push payload 规范(建议)
6.1 设计目标
- 足够定位:能让客户端知道要刷新哪个订单/运单、点击去哪里。
- 不泄露敏感:不含手机号/地址/raw_payload。
- 可审计:含平台侧 message_id / request_id。
6.2 字段建议(透传/通知通用)
{
"biz": "express",
"aud": "user",
"message_id": "msg_xxx",
"order_no": "ORD_2026...",
"carrier": "YTO",
"tracking_no": "YT123...",
"status_code": "OUT_FOR_DELIVERY",
"event_time": "2026-02-05T14:32:00+08:00",
"event_text": "快件正在派送中",
"deeplink": {
"path": "/pages/order/detail",
"query": {"order_no":"ORD_2026...", "tab":"logistics"}
}
}
说明:
event_text推荐使用“清洗后的文案”(避免把第三方原文中的手机号明文透传)。aud:区分用户端/商家端,有利于同一 App 多角色或同一推送通道多消费方。
6.3 通知栏标题/摘要建议(示例)
- 用户端:
- 标题:
物流更新/订单物流更新 - 内容:
【派送中】快件正在派送中
- 标题:
- 商家端:
- 标题:
订单履约提醒 - 内容:
【异常】包裹地址不详正在退回(异常优先级最高)
- 标题:
7. 消息中心与未读(服务端为准)
7.1 为什么需要消息中心
- Push 可能丢失/被系统拦截;消息中心提供可回溯记录。
- 多设备登录需要统一未读。
7.2 建议的数据模型(平台侧新增)
建议新增两类表(命名仅示例):
- 设备注册表
push_devices
iduser_id/merchant_id(二选一或用统一 subject)cidplatform(android/ios/web)appid(用于区分环境)last_seen_at、is_active
- 物流消息表
express_notifications
id(message_id)aud(user/merchant)recipient_idorder_id/order_no、waybill_id、tracking_no、carrierstatus_code、event_time、event_text_saferead_at(或拆到 read 表做多端多设备)created_at- 幂等键(unique)
7.3 API(建议)
- 设备注册:
POST /api/v1/push/register(登录后上报 CID,绑定到账号) - 设备解绑:
POST /api/v1/push/unregister - 消息列表:
GET /api/v1/notifications?biz=express&aud=user|merchant&page=... - 标记已读:
POST /api/v1/notifications/read(按 message_id 或按订单批量) - 未读数:
GET /api/v1/notifications/unread-count?biz=express&aud=...
8. 点击跳转(deeplink)
8.1 跳转原则
- 点击通知后进入“订单详情-物流区块”或“物流详情页”。
- 页面打开后必须调用平台查询接口刷新
status_history。
8.2 跳转目标建议
- 用户端:订单详情页(展示物流时间线)
- 商家端:订单详情页(展示物流时间线 + 发货信息)
- 平台后台:不通过 App push 跳转(后台有自己的排障页)
9. 安全、权限与隐私
9.1 收件人权限校验
- 用户端:仅能收到/查看自己订单的物流消息。
- 商家端:仅能收到/查看自己店铺订单的物流消息。
服务端生成消息时必须校验:order_no -> 订单归属 -> recipient。
9.2 敏感字段控制(强约束)
- 禁止通过 push payload/通知文案下发:完整手机号、完整地址、raw_payload、签名/密钥。
raw_payload仅允许客服/运维在后台折叠查看,并记录审计。
9.3 CID 绑定安全
- CID 必须在登录态下上报并绑定到账号。
- 更换设备/卸载重装:CID 可能变化,需更新绑定。
- 退出登录时建议解绑或标记设备 inactive。
10. 失败与补偿
- 推送失败(CID 失效/不属于应用):标记设备 inactive 并等待下次登录刷新。
- Webhook 入库成功但推送失败:不影响事实数据;消息中心仍可查询到记录(若已写入消息表)。
- 客户端未收到 push:用户进入订单详情时仍能通过查询接口看到最新轨迹。
11. 验收清单(与联调口径一致)
- 插入一条轨迹事件(模拟 webhook)后:
- waybill
current_status_code/text更新 - events 表新增且幂等
- 消息中心新增 1 条(不重复)
- 目标端(用户/商家)收到推送
- 乱序/重复推送:
- 事件表不重复、消息中心不重复
- 当前状态不回退(按平台选定算法)
- 隐私校验:
- push 文案与 payload 无手机号明文/无 raw
- 点击跳转:
- 落到订单/物流详情页并刷新出最新时间线
12. 与本目录文档的对应关系(索引)
- 统一模型与 Webhook 约束:接口规范
- 状态映射:状态映射表
- 展示字段与隐私规则:前端字段清单
- 生产表结构与幂等/乱序:生产表说明_platform_express
- 移动端 push 联调与 CID 归属:uni-push2 安卓联调与取 CID 说明