他买的是这瓶牛奶,装进袋子的是哪一瓶,由两小时后站在货架前的人决定

他买的是这瓶牛奶,装进袋子的是哪一瓶,由两小时后站在货架前的人决定
张文保 79 分钟阅读 3,838 阅读
本文目录
  1. 用户勾的那个允许替换,兑现的时候他人在哪里?
  2. 用户签的那个字,兑现的时候他不在场
  3. 他想说的是一句带条件的话,系统存下来的是一个布尔值
  4. 三句判据,把这件事从生鲜站里拎出来
  5. 同一个模式,你的站上还有几个实例
  6. 这一篇不打算谈的几件事
  7. 为什么这一段时间最没有界面
  8. 为什么这个品类值得单独花一篇的篇幅
  9. 那句话传到拣货员手里,还剩几个字?
  10. 把一次替换拆成五只手
  11. 第2步这个字段,是整条链路上最贵的一次压缩
  12. 第3步的人,缺的不是规则而是理由
  13. 第4步是整条链路上最便宜的一个补丁
  14. 第5步,让用户自己去袋子里发现
  15. 五只手里,只有一只有界面
  16. 把这张表当成一次分工会议的议程
  17. 想指定替代品的人,为什么在购物车里翻不到那个开关?
  18. 两个测试记录,中间隔了四年
  19. 隔了四年、两个不同的站、两拨不同的用户,卡在同一个地方
  20. 这句话对做竞品调研的人是一记提醒
  21. 为什么它偏偏被放在结账里
  22. 不用搬功能,先把话说到位
  23. 顺带算一笔账:这条信息值多少
  24. 同一条元方法论,在SEO这一侧也成立
  25. 别的品类缺货可以等,为什么生鲜只能换?
  26. 一般电商的缺货解法,是拿时间换库存
  27. 那些看上去很贴心的替代方案,效果都不好
  28. 可是生鲜没有这段时间可以拿来换
  29. 为什么这个功能长得这么潦草
  30. 时间不能换,但可以换一种换法
  31. 把这一节的判断浓缩成一句
  32. 还有一类站会被这个判断误伤
  33. 给50件商品逐件挑替代品,是体贴还是酷刑?
  34. 逐件确认在3件时是体贴,在50件时是酷刑
  35. 把授权做成分层的,而不是逐件的
  36. 默认值该倒向哪一边
  37. 那么到底该选哪个
  38. 还有一个更省事的口子:让他先说不能换什么
  39. 验收只需要一个动作
  40. 如果非要做逐件,至少别让他从零开始想
  41. 他选中的那个配送时段,为什么到结账才说没了?
  42. 一个测试记录:走到结账才发现今天没时段了
  43. 时段是一种库存,而且是最难缠的那种
  44. 还有一层:时段的稀缺不是均匀分布的
  45. 信息出现得晚,代价按已投入的时间算
  46. 三个位置,越早越好
  47. 不能预约未来时段,是一个产品决定不是技术限制
  48. 这一屏还藏着一个SEO口子
  49. 点了更改却改不了履约方式,问题出在哪一层?
  50. 点了“更改”,改到的不是他想改的那件事
  51. 履约方式在你的库里是订单级的,在他脑子里是购物车级的
  52. 更严重的一种:一个购物车里混着两种履约方式
  53. 三个改法,成本从低到高
  54. 顺便修一下按钮上的字
  55. 混合履约还牵着一条SEO上的线
  56. 上次买过的那罐,为什么要翻到购物车最底下才找得到?
  57. 用户为了买一罐上次买过的东西,跑到了购物车底部
  58. 订单是按时间切的,复购需要按商品切
  59. 这个品类里,复购是主路径不是快捷方式
  60. 一个对做SEO的人很不舒服的数字
  61. 列表页那个每单位价格,正好也在这一屏
  62. 复购列表还顺手解决了替换的一半问题
  63. 缺货这个状态,页面、商品数据和抓取程序看到的是同一个吗?
  64. Google要求四个地方口径一致,而它自己在这句话里数漏了一个
  65. 12个格子映射到4个格子,有两个无处可去
  66. 压缩不是均匀发生的,它专挑一类值下手
  67. 落地页那几条硬要求,比看上去严
  68. 抓取程序不会替用户选门店
  69. 那这一层到底该怎么处理
  70. 门店页那一层,比想象中值钱
  71. 一个可以今天就跑的自查
  72. 再往前一步:AI购物那一侧要的是同一份数据
  73. 不加一行埋点先算哪几个数,改完之后哪个数会骗你?
  74. 五个数,全都来自你已经存了很多年的东西
  75. 四格交叉:替换发生率乘以复购频次
  76. 有一个数不建议算
  77. 一次失手复盘:修好了替换,却在另一个入口上失血
  78. 问题出在一个谁都没想到会有影响的改动上
  79. 这次的预警形态:报警响了,但响在了另一个人的收件箱里
  80. 三档投入,按能不能立刻验收排
  81. 三条停手信号
  82. 立项时怎么说
  83. 先从哪个品类开刀
  84. 最后留一条给做SEO的人
  85. 常见问题解答
  86. 缺货替代品的默认值到底该设成允许还是不允许?
  87. 替代品的选择功能该放在购物车还是结账?
  88. 生鲜站的缺货处理为什么不能照搬一般电商那一套?
  89. 给几十件商品逐件设置替代品,用户真的会做吗?
  90. 怎么在不加埋点的情况下证明这件事值得投入?
  91. 库存状态在结构化数据和商品数据文件里为什么老是对不上?
  92. Googlebot看到的商品页库存,跟真实用户看到的是同一份吗?
  93. 权威参考资料

摘要:生鲜站有一个别的品类没有的机制:下单时那件商品还在,两小时后拣货员站到货架前它没了,于是换一件塞进袋子。用户勾的那个“缺货可替换”,是在替一个他不在场、由别人执行的决定提前签字。Baymard在2022年测Walmart、2026年测CVS,隔了四年两个站,用户都在购物车里翻不到那个开关;给50件商品逐件挑替代品会直接把人压垮弃单。这篇把授权在三次转手里降的两次维拆开,把页面、商品数据和抓取程序看到的三份缺货状态摆进同一张表,再给五个不用埋点的指标和一次失手复盘。

用户勾的那个允许替换,兑现的时候他人在哪里?

他在睡觉。而拿着拣货单站在货架前的那个人,手上只有一个绿色对勾。

用户签的那个字,兑现的时候他不在场

先把场景摆具体。周三晚上,一个用户在某生鲜站上加满了一车东西,四十来件,里面有一瓶指定牌子的有机全脂牛奶。他选了周四上午9点到11点送达,结账时页面上有一行小字加一个勾选框:如果商品缺货,允许用最相近的商品替换。他勾了,付款,关掉页面,去睡觉。

周四早上7点40分,仓库里一个他从没见过、也永远不会见到的人,拿着拣货单站在乳品柜前。那瓶有机全脂牛奶昨晚被别人买走了。这个人手上的设备显示这一行是绿色的对勾,意思是允许替换。他伸手拿了旁边一瓶普通全脂,扫码,放进袋子,继续下一行。

9点20分,牛奶送到。用户打开袋子,看到不是他要的那瓶。他没有投诉,也没有退货——退一瓶牛奶的力气比这瓶牛奶本身值钱。他只是记住了这件事。三周之后他换了一家买菜。

这条链路上没有任何一个环节出错。用户勾了框,系统存了状态,拣货员照规则执行,配送准时。整件事的问题在于,用户当时想说的那句话,和最后被执行的那件事,中间隔着两次降维,而这两次降维没有任何一个界面记录下来

他想说的是一句带条件的话,系统存下来的是一个布尔值

用户勾那个框的时候,脑子里那句完整的话大概是这样:这瓶有机全脂如果没了,同品牌的低脂可以,或者别的牌子的有机全脂也行,但不要给我拿普通牛奶——我买它就是为了那个有机。

系统存下来的是allow_substitution = true

拣货员看到的是一个绿色对勾。

这是本文要讲的整件事的核心:同一份授权在三次转手里降了两次维。一句带条件、带优先级、带底线的话,先被压成一个布尔值,再被渲染成一个视觉符号。到执行的那一刻,原话里所有的信息都没了,只剩下“可以换”三个字

而这三个字在用户嘴里和在拣货员眼里,含义完全不同。用户说的是“在我说的范围内可以换”,拣货员读到的是“随便换都行”。

三句判据,把这件事从生鲜站里拎出来

这个模式不只长在生鲜站上。任何一个界面,只要它请用户为一件将来才发生、且他不在场的事提前表态,就适用下面这三句。

第一句:用户在这一屏上勾的这个选项,真正兑现是在什么时候?他那个时候在不在场?如果兑现和表态之间隔着几小时甚至几天,而中间没有任何一次回头确认,这就是一次缺席授权。

第二句:到兑现那一刻,真正拍板的是谁?他手上拿到的是用户的原话,还是一个被压缩过的标志位?这一句最容易被跳过,因为写界面的人默认自己存进数据库的那个字段就是用户的意思,而它通常不是

第三句:决定做完之后,用户是先知道还是后知道?能不能推翻?推翻的成本落在谁身上?如果答案是“后知道、不能推翻、成本全在用户那边”,那这个授权在设计上就是单向的。

同一个模式,你的站上还有几个实例

把三句判据拿去过一遍,会发现缺席授权在电商里到处都是,只是别的品类里它出现的频率低,所以没人给它起过名字。

界面位置用户提前表的态兑现时拍板的人他事后能不能推翻
生鲜缺货替换允许替换拣货员,看着货架到货才知道,基本不推翻
定制商品的打样确认按这个稿子做工厂,按自己的色差标准做完了才看到成品
订阅制的下一期扣款同意自动续费系统,按续费时的价目表扣完才收到邮件
按重量计价的散装商品下单时那个估算价秤,按实际称重结算金额和下单金额不同
预售商品的最终规格按页面上写的配置供应链,按到货批次发货后才发现换了供应商
B2B报价单有效期接受这个价格业务,按下单时的汇率合同签完才对账
无人在家时的放置授权可以放门口快递员,按现场判断丢了才知道放在哪

七行里最后一行最有意思:它是唯一一个大多数平台已经做出回执的——快递员放下包裹要拍一张照片。同样是缺席授权,物流那一侧早就意识到“事后得让用户看到执行结果”,而商品替换这一侧至今还停在“事后让用户自己去袋子里找”

这一篇不打算谈的几件事

有几个话题跟它长得很像,发生的时间段却不一样,混在一起讨论会把判断搞乱。先划清楚。

一是下单前你承诺的那个日期。用户记住的日期和你算出来的日期对不上,那是你写的是2个工作日,他记的是周四讲的事,发生在付款之前,对象是时间不是商品。

二是用户下单后想撤。那是发货前被你拒掉的那次取消,主动方是用户;本文里主动方是你,用户连自己被动了都还不知道

三是付完钱那一页要写什么,在用户付完钱看到的那一页里;四是发货之后他天天来查到哪了,在你的跟踪页却把他一脚踢到了第三方站上里。这两件事一个在替换之前、一个在替换之后,本文卡在它们中间那一段。

五是商品彻底下架之后的收尾,301还是410还是软404,那是Magento产品缺货下架后SEO怎么收尾的范围。那篇处理的是“这个商品永远没了”,本文处理的是“这一单的这一件临时没了,而商品本身明天还在卖”——两者在数据库里是同一个库存字段,在SEO上要走完全相反的处理

为什么这一段时间最没有界面

把整条链路画出来会看到一个反差:从加购到付款,用户每一步都对着一块屏幕,每一屏都被反复优化过;从付款到拣货,用户手上一块屏幕都没有,而替换恰好发生在这一段。

所有电商的界面设计精力都投在用户看得见的那几屏上,而这件事发生在整条链路里唯一一段没有屏幕的时间里。这解释了为什么它长期没人管:没有页面,就没有页面负责人;没有页面负责人,就没有人在周会上提它。

保哥带团队做过一次很土的验证:把一个季度里所有发生过替换的订单拉出来,统计这些用户在替换发生后的第30天还有没有回来下单,再跟同期没发生过替换的订单比一次。这个数字不需要任何埋点,订单表里全都有。

为什么这个品类值得单独花一篇的篇幅

可能有人会想,生鲜杂货离自己的业务挺远,值得读这么长吗。有两个理由。

第一个理由是这个品类的整体水位低得离谱。Baymard对10个生鲜站与应用做过的基准测试显示,整体表现全部落在“差”这一档,而电商大盘的平均水平是“中等偏尚可”。更具体一点:这10个站里表现最差的一块恰好是购物车与结账,桌面和移动几乎全线飘红。一整个品类都没及格,意味着这一格里随便做对一件事都是差异化

第二个理由更重要:缺席授权这个模式在别的品类里也存在,只是频率低到不足以被单独讨论。生鲜把它的频率放大了几十倍,于是所有的裂缝都露了出来。这跟做技术调优时故意加压是一个意思——你不是为了看它在高压下怎么跑,是为了看它先从哪儿裂。

所以这一篇里绝大多数结论都能直接搬走。定制、预售、订阅、按重量计价、放置授权,任何一个让用户提前替不在场的自己表态的场景,判据和解法都是同一套。

那句话传到拣货员手里,还剩几个字?

一次替换要经过五只手,用户只在第一只手里出现过,而他说的那句话在第二只手里就被压成了一个布尔值。

把一次替换拆成五只手

先把链路完整列出来。一次替换从头到尾要经过五个环节,而用户只在第一个环节里出现过。

环节谁在动他手上有什么信息在这一步损失了什么
1表态用户一句带条件的完整意思界面只给他一个勾选框
2存储系统订单表里一个字段条件、优先级、底线全没了
3判断拣货员一个绿色对勾加自己的常识他不知道用户为什么买这瓶
4通知系统或没人一条短信,或者什么都没有多数站在这一步是空的
5收货用户一个袋子他得自己发现被换了

把这张表放到会上,讨论会立刻变得具体:多数团队会发现自己只做了第1步和第2步,第3步交给了仓库的作业规范,第4步压根没人负责,第5步默认用户自己看。

第2步这个字段,是整条链路上最贵的一次压缩

数据库里那个字段通常长这样:一个布尔值,或者一个三选一的枚举——允许替换、不允许替换、缺货就退款。做技术的人看这个设计没什么毛病,它简洁、好存、好查、好统计。

问题在于它的定义域和用户意图的定义域完全不是一回事。用户的意图是一个带偏好排序的集合,你存的是一个点。集合压成点,压缩比是无限大,而这一步没有任何一个界面提示“你刚才的意思被简化了”

可以做个对照:同样是让用户提前表态,配送地址你就没敢压缩。你不会给用户一个“地址随便填得差不多就行”的勾选框,你老老实实收了国家、省市、街道、门牌、邮编五六个字段,因为你很清楚地址错一位包裹就丢了。

替代品这件事的后果没那么剧烈,所以它被允许用一个布尔值糊过去。但两者的性质是一样的:都是用户在你这里留下的、将来要被别人照着执行的指令

换个角度看,这个字段的问题在于它没有“程度”

还有一个更细的观察:那个字段不但丢了条件,还丢了强度。

用户对不同商品的坚持程度差别极大。同一张购物车里,白糖换个牌子他完全无所谓,婴儿米粉换个牌子他可能直接拒收。而现在的设计里,这两件商品共用同一个整单开关,等于宣布用户对所有商品的坚持程度是一样的

这个假设显然不成立,而它之所以能长期存在,是因为纠正它的成本看上去很高——听起来要给每件商品加一个设置。后面会讲到,其实不用。

第3步的人,缺的不是规则而是理由

拣货员不是在偷懒,他手上的信息就那么多。他知道这一行允许替换,不知道用户为什么买这瓶——是因为孩子对某种成分过敏,是因为在做一道菜必须用全脂,还是单纯因为便宜。

这三种理由对应三种完全不同的替换策略,而它们在系统里长得一模一样。

更有意思的是,用户往往愿意说。只要在商品行右边放一个可选的输入框,一部分用户会写下他的理由和他的备选,而这些信息不需要你去猜、不需要建模型、不需要跑算法——他会免费告诉你,前提是你得先给他一个能写的地方

保哥见过的做法里最省事的一种:不做逐件输入,只在结账页加一行整单说明,写“有哪些东西是绝对不能替换的,可以在这里写一句”。愿意写的人不到两成,但写的人正好就是替换出事之后最容易流失的那两成。

顺便说一个反例:同样的信息,客服那边是有的

有意思的是,同一个站的客服系统里往往留着完整的用户意图。用户打电话进来说“我上次那个牛奶被换了,我买它是因为孩子只喝这个牌子”,客服会把这句话原样记进工单。

也就是说,这句话在你的公司里存在过,只是它出现在事后而不是事前,出现在客服系统而不是订单系统。同一条信息,早两小时拿到能避免一次失望,晚两小时拿到只能用来道歉,而多数站的架构决定了它只能晚拿到

把这件事反过来用就是一个很省事的调研方法:翻一个月的替换类工单,把用户自己写的理由归归类。这批文本是免费的需求说明书,而且它比任何一次问卷都真实,因为写它的人当时是真的不高兴

第4步是整条链路上最便宜的一个补丁

五个环节里,第4步的改造成本最低而效果最直接:在替换发生的那一刻发一条通知,写清楚原来是什么、换成了什么、差价怎么处理,给一个可以点的拒收链接。

这一步之所以长期空着,原因很务实:替换发生在拣货时,而拣货和配送之间往往只有一两个小时,产品经理会问“通知了他也来不及改,有什么用”。

这个反驳听上去成立,但它把通知的作用理解窄了。通知的第一作用不是给用户留出反悔的时间窗,是把一次静默的替代变成一次有记录的替代。用户知情之后,他的不满会变成一次客服对话或者一次点击,而不是三周后一次无声的流失。

而且从数据上说,这一条通知是你唯一能拿到“用户接受了这次替换吗”这个答案的地方。没有它,替换的成功率永远是个未知数——你只知道发生了多少次替换,不知道其中有多少次让人不痛快。

第5步,让用户自己去袋子里发现

大部分站的现状是这一步什么都不做。订单详情页上还是原来那件商品的名字和图,实际送到的是另一件,两者在页面上从来没对上过。

这里有个很小但很值钱的细节:订单详情页应该保留两行——原来下单的那件,和实际交付的那件,并列显示,不要用后者覆盖前者。覆盖会带来一个很尴尬的后果:用户想投诉的时候找不到证据,因为页面上写的就是他收到的那件,他会开始怀疑是不是自己记错了。

这个做法在别的场景里早就是常识。商品页上被划掉的那个原价之所以要留一份价格历史,逻辑完全一样:发生过变更的地方,变更前的那个值本身就是证据,把它擦掉等于把举证责任转移给了用户

通知的文案有一个很容易写坏的地方

这条通知的措辞值得多花十分钟。常见的写法是“您的订单中有商品已被替换”,这句话在信息上没错,但它把一次替换写成了一件已经完成的事,用户读完只剩下接受。

换一种写法:写清楚原来是什么、换成了什么、价格怎么算,然后给一个“这个不要,退款给我”的按钮。同一件事,前一种写法是通知,后一种写法是征询,而它们在系统里的实现成本几乎一样

价差这一条尤其要写死。替换过去经常是往贵了换,因为拣货员会拿旁边那个更大规格的。如果差价规则不写在通知里,用户会在银行账单上自己发现它,那时候这件事的性质就从“帮我换了个牌子”变成“多扣了我钱”

五只手里,只有一只有界面

回头看这张表会发现一个很不舒服的事实:五个环节里只有第1步和第5步用户能看见,而第5步多数站还是空的。也就是说,整条链路上用户唯一的接触点,是最开始那个勾选框。

他要凭那一个勾选框,信任后面四步都会照他的意思走。这在设计上叫什么都行,唯独不能叫“给了用户选择权”

把这张表当成一次分工会议的议程

这张五只手的表还有一个用法:直接当会议议程。把五行贴在白板上,让每一行认领一个负责人。

结果通常很尴尬。第1步归前端,第2步归后端,第5步归客服或者归“用户自己”。第3步和第4步经常没有人举手——第3步在仓库,仓库的人不参加这个会;第4步是通知,而通知在多数公司归“消息中心”,那是一个只提供通道不负责内容的团队

无主的环节恰好是出问题最多的两个,这不是巧合。商品页上那个推荐位,两套报表算出相反的结论那篇里也出现过类似的形状:一件事只要跨过两个团队的边界,边界上那一段就会同时被两边当成对方的事

想指定替代品的人,为什么在购物车里翻不到那个开关?

2022年测Walmart,2026年测CVS,隔了四年两个不同的站,用户卡在同一个位置。界面早就改过好几轮了。

两个测试记录,中间隔了四年

Baymard在2022年那一轮生鲜研究里,测试者在Walmart的移动应用上把购物车从上翻到下,想找替代品设置。她一边翻一边说:我不知道他们做不做替换,看起来不做。

她还解释了为什么这件事对她重要——她去店里取过货,结果半个订单都是缺的,很烦人。

而Walmart的应用其实是有这个功能的,位置在结账流程再往后一点。功能存在,用户找不到,于是她在购物车这一步就已经开始犹豫要不要继续下单

时间跳到2026年。Baymard新一轮生鲜研究里,一位测试者在CVS的移动站上做了几乎完全一样的动作:在购物车里上下滚动,找不到任何指定替代品的入口。她的原话是:我是真的在这上面看不到任何地方能做这件事。我回到顶部再看看,再一路拉到底。嗯,不行,我不知道。

CVS的这个功能同样存在,同样只在结账流程里出现。

隔了四年、两个不同的站、两拨不同的用户,卡在同一个地方

这两个记录放在一起,价值远超它们各自。2022年到2026年,这两个站的界面几乎不可能没改过——四年时间足够一个大站重做两轮设计系统,换掉字体、换掉配色、把圆角改成直角再改回去。

可用户遇到的障碍纹丝不动。

Baymard自己在这一轮研究里写了一句很值得抄下来的话:一个来自用户测试的例子看上去过时了,并不意味着它背后的那个用户问题已经不存在——变的往往只是界面外观,因为新的设计风潮来了

这句话对做竞品调研的人是一记提醒

把这条元方法论从生鲜站里拎出来,它适用于任何一次竞品分析和任何一次案例引用。

常见的错误是这样的:你在一份研究报告里看到一张2022年的截图,第一反应是“这早就改了吧”,于是跳过。你拿视觉年代替代了问题年代,而这两个年代的更新速度差着一个数量级

界面每年都在变,因为设计有流行;用户在履约链路上遇到的结构性障碍很多年不变,因为它不是设计问题,是数据模型和职责划分的问题。而后者的改动要跨部门,跨部门的事推不动。

保哥做竞品拆解时养成的一个习惯是:看到旧截图先别管界面长什么样,直接问一句“这个问题的成因在哪一层”。如果成因在视觉层,那它大概率真的改了;如果成因在数据模型或者流程职责上,那它八成还在,只是穿了一件新衣服

怎么判断一张旧截图还值不值钱

这条判断可以再具体一点,给三个可以直接问的问题。

第一,这张截图记录的是一次视觉呈现,还是一次用户行为?如果它记录的是用户说过的一句话、做过的一串动作,那它基本不会过期,因为人在这类场景下的行为方式几十年没怎么变

第二,这个问题要修的话,需要几个团队点头?一个团队能改完的,四年过去大概率改了;需要三个团队协调的,四年过去大概率还在原地。

第三,这个问题有没有一个持续存在的动因让它保持原状?替代品这件事就有:它的功能位置由数据就绪时间决定,而那个技术约束这四年一点没变,所以它必然还在同一个地方

为什么它偏偏被放在结账里

值得想一下这个功能为什么会长在结账流程里,而不是购物车里。这不是随便放的,它有一个非常自然的技术理由。

替代品逻辑依赖三样东西:知道用户从哪个门店取货或者由哪个仓发货,知道那个点的实时库存,知道这一单最终包含哪些商品。这三样在购物车阶段都还没定死——用户可能换门店,可能改地址,还在往里加东西。而到了结账,履约点确定了,商品清单基本冻结了,做这个功能最省事。

所以从后端往前看,放在结账是对的;从用户往后看,购物车才是他会去找的地方。这两个视角的分歧不是谁对谁错,它是这类问题的典型形状:功能的位置由数据的就绪时间决定,而用户的寻找位置由他的心理任务决定,两者没有任何理由重合

不用搬功能,先把话说到位

好消息是,这个问题的第一版解法不需要动那套依赖关系,只需要在购物车里放一句话。

比如在购物车靠近结算按钮的地方写一行:结账时你可以逐件指定缺货怎么处理。一行字,前端一个人半天,不需要任何后端配合,也不需要把替代品逻辑提前到购物车。

这里的关键区分是:用户在购物车里需要的不是那个功能本身,是“这个功能存在”这条信息。他之所以犹豫,不是因为现在就要设置,是因为他不确定这个站到底管不管这件事。

这一点和那4张没露出来的商品图是同一类问题的两个变种:那边是内容存在但页面没说,这边是功能存在但流程没说。两边用户的动作也一样——都是什么都不做,然后带着一个错误的结论离开

那句提示写在哪一行,差别不小

位置有讲究。写在购物车最上面的通栏里,用户往下滚就再也看不到了;写在每一件商品下面,四十件商品重复四十遍,视觉上直接变成噪声。

比较稳的位置是紧挨着结算按钮的上方。用户在按那个按钮之前一定会往那个区域看一眼,因为那里通常还写着总价和运费,他的注意力本来就在那儿

另一个可选位置是购物车的空态和加载态。这两个状态的页面上没什么内容,塞一句功能说明既不挤地方,又能被新用户看到——而新用户恰好是最需要这条信息的那批,老用户早就知道你管不管这件事了

顺带算一笔账:这条信息值多少

把这行字的价值量化一下并不难。购物车到结账那一步的流失率你的报表里一定有;只要做一次前后对比,看这行字上线之后这一步的流失有没有动。

需要提醒的是别指望它有很大的绝对值。受这句话影响的只是那批“在意替换、且正在犹豫”的用户,他们在总量里占比不高,但他们恰好是最容易变成长期客户的那批人——因为他们已经在认真规划这一单了。

顺着这个思路还有一个更省事的验证:翻一周客服记录,数一数有多少人在下单前问过“如果没货了怎么办”。这个数字不需要埋点,也不需要等实验,今天下午就能有答案。

同一条元方法论,在SEO这一侧也成立

“截图看着过时不代表问题消失”这句话,换个对象放到搜索这边同样管用,而且踩坑的人更多。

常见的场景是:有人在一篇2021年的文章里看到某条技术做法,第一反应是“这么老的东西早就不适用了”,于是跳过。但搜索引擎的很多机制稳定得惊人——抓取要花预算、重复内容要选规范版本、跳转会稀释信号,这些十年前成立,今天照样成立。变的是围绕它们的产品形态和界面。

反过来也有陷阱:确实有一批东西过期得极快,比如某个具体的富媒体类型支不支持、某个后台报表在哪个菜单下面。提交网站地图能提升Google排名吗那类文章要处理的就是这种混淆——把一个机制层的事实和一个产品层的现状混为一谈。

判断办法跟看竞品截图一样:先问这条说法的成因在哪一层。成因在产品界面,那它大概率已经变了;成因在协议、成本或者组织分工,那它八成还在

别的品类缺货可以等,为什么生鲜只能换?

线上购物天生带一段等待期,这是你手上现成的一笔时间。可牛奶用不上它。

一般电商的缺货解法,是拿时间换库存

先看看别的品类怎么处理缺货。Baymard在关于暂时缺货商品的那篇研究里给过一条很反直觉的建议:暂时缺货的商品,应该继续让用户下单,只是把配送时间加长。

理由是线上购物天生带着一段等待期。用户在实体店里买不到就是真的没有,他得空着手走出去;但在网上,他从下单到收货本来就要等几天,这段等待期是你手里现成的一笔额外时间,而多数站白白浪费了它

Baymard给的例子是一条裙子,红色特别好卖所以经常断货,其他颜色卖得慢。既然红色补货是确定的、周期也不长,那就让用户照常结账,把这一件的交期往后推一两天,而不是把加入购物车按钮拿掉。

而这件事的现状是:基准测试里68%的站不让用户为暂时缺货的商品下单

那些看上去很贴心的替代方案,效果都不好

被广泛采用的两个替代做法是“到货通知我”和“加入收藏”,两个的测试表现都不理想。

到货通知的问题在于它的潜台词。Baymard的说法很直接:这个按钮等于在跟用户说,现在别买了,等我们有货了你再回来。而用户听到这句话的时候,脑子里想的是去别家看看——他要等的话,为什么不等一个能马上买到的地方

收藏功能的问题更实在:基准测试显示75%的站要求用户先注册账号才能用保存功能。而Baymard关于弃单原因的定量研究里,19%的美国网购者在过去一个季度里,仅仅因为被强制注册就放弃过至少一次购物车

把两个数字乘在一起就知道这条路有多窄:你为缺货商品准备的退路,需要用户先跨过一道全站流失率最高的门槛之一。

顺带一个可以直接用的数:测试里看到缺货之后有30%的用户直接弃站去别处找,只有一部分会在你站内找替代商品。这个比例足够高,高到值得单独排一次期。

顺手把这几个数用在自己的排期表上

这三个数放在一起,可以直接支撑一次很短的排期讨论。看到缺货就走的那30%,是你在缺货这件事上的最大一笔损失;而68%这个数说明多数同行也没做,所以这一格是空的

而75%和19%那两个数的用法不一样,它们是用来否掉一个方案的。每当有人提议“缺货就让用户加收藏吧”,把这两个数摆出来:这条路的入口挡着一道全站流失最高的门槛之一,你等于把缺货用户又筛掉了一层

顺带一提,强制注册这件事本身也是用户付完钱看到的那一页里提过的老问题,两边可以对照着看:凡是在流程的关键节点上插进一道账号墙,代价都远比团队预估的高

可是生鲜没有这段时间可以拿来换

把上面那套逻辑搬到生鲜站上,它整个塌掉。

红裙子晚两天到没关系,用户买它是为了下个月的婚礼。一瓶牛奶晚两天到就没有意义了——用户买它是为了明天早上,交付时间不是这一单的成本项,它是这一单存在的理由

这就是整件事的立论:一般电商可以用时间换库存,生鲜换不了。所以别的品类里缺货的解法是延后,生鲜里唯一可用的解法是替换

换句话说,替代品机制不是生鲜站多做的一个贴心功能,它是这个品类被逼出来的唯一解。这个认识很重要,因为它决定了这件事该排在优先级的哪一格:它不是锦上添花,它是这个品类的缺货处理主流程

为什么这个功能长得这么潦草

既然是主流程,它为什么普遍做得这么粗糙?一个很实在的原因是它长在别人家的模板上。

大部分生鲜站的电商系统是通用平台改的,而通用平台的缺货模型只有两档:有货、没货。替代品是一个只有这个品类才需要的第三档,平台没有,于是被当成一个附加需求塞在结账流程的角落里,用一个勾选框打发掉

这也解释了为什么它的界面质量跟同一个站上别的模块差那么多。购物车、结账、支付都是平台自带的成熟模块,被无数个站打磨过;替代品这一块是自己接的,接的时候排期紧,能跑就行。

时间不能换,但可以换一种换法

严格说,生鲜也有一类可以用时间换的场景,只是范围窄得多——干货、罐头、清洁用品、纸品这些不着急吃的东西。

这里有一个很少人做但成本极低的分档:把商品按“能不能等”分两类,缺货时走两条完全不同的路。牛奶鸡蛋蔬菜这类走替换,纸巾洗衣液这类问一句“这件可以晚两天单独送吗”。

这个分类不需要新建字段,多数站的商品分类树上早就有生鲜与非生鲜的划分,直接拿来用就行。

保哥在做这类盘点时的经验是,团队最容易忽略的是第三类:那些用户明明可以等、但你默认给他换掉的商品。他买的是一个特定牌子的挂耳咖啡,被换成了另一个牌子的速溶——而他其实完全愿意等三天。这一类的替换损失最大,因为它本来根本不该发生。

顺手把这个分类做成一个字段

如果决定要做这个分档,建议直接在商品数据里加一个字段而不是靠分类树推。分类树是给用户看的,它的划分依据是购物习惯;能不能等是一个履约属性,两者在大多数商品上重合,但在少数商品上会打架

典型的打架例子是冷冻食品:它在分类树上属于生鲜,但它其实很能等,只要冷链跟得上。而一束在分类树上属于家居装饰的鲜花,一天都等不了。

加这个字段的好处不止于缺货处理。一旦有了它,履约标签、时段规则、退货政策、包装方式全都能挂上去,而这几件事现在多半是各写各的逻辑,各有一套自己的判断

把这一节的判断浓缩成一句

做优先级判断的时候可以用这句话:先问这个品类的交付时间是不是购买动机本身。是,缺货就必须当场解决,替换是主流程;不是,缺货可以拿时间换,替换反而是下策

按这个标准过一遍,鲜花、蛋糕、餐食配送、药品、宠物鲜粮都落在第一类;服装、家居、3C、图书落在第二类。而混合业态的站最麻烦——同一个购物车里两类商品都有,它需要两套缺货逻辑同时运行,这一点后面还会再碰到

还有一类站会被这个判断误伤

有一类站落在中间,判断的时候容易搞错:礼品和节令商品。

母亲节前三天下单的一束花,交付时间当然是购买动机;但同一个站在平时卖的绿植,晚两天完全没关系。同一个商品,同一个页面,交付时间的性质随日期变化

这类站的处理方式是把判断从商品挪到订单:看用户有没有在下单时指定一个具体的送达日期。指定了就走替换逻辑,没指定就可以走延后逻辑。这个信号你已经有了,就在订单里,不需要给商品新增任何字段。

顺便说,礼品单还有另一层复杂度——收件人和下单人不是同一个人,替换通知该发给谁是个真问题。买家勾了这是礼物,可你的整条跨境链路从头到尾只认得买家一个人那篇专门算过这条链路,本文就不展开了。

给50件商品逐件挑替代品,是体贴还是酷刑?

同一个交互设计,在购物车只有三件的品类里是贴心,在这里能把人直接赶走。变量只有一个。

逐件确认在3件时是体贴,在50件时是酷刑

Baymard在生鲜研究里记了一个很具体的失败:测试中有些用户面对给50多件商品逐个选择替代品这件事,直接被压垮,弃站了。

这个记录值得停下来看两眼,因为它推翻了一个很自然的设计直觉。逐件指定替代品,从任何一个角度看都是更尊重用户的设计——给的选择更多,颗粒度更细,用户的意图被更完整地保留下来。它唯一的问题是,用户干不动

把它放回本文的框架里:第1步那个“表态”的成本,随着商品件数线性增长,而这个品类的购物车是所有品类里最长的。别的站购物车两三件,生鲜站四五十件。同一个交互设计,在一个品类里是贴心,在另一个品类里是刑罚,差别只来自购物车长度这一个变量

把授权做成分层的,而不是逐件的

解法不是在逐件和一刀切之间二选一,是把它做成分层的:默认一个整单策略,只让用户对少数几件做例外标记。

层级用户要做的动作覆盖的商品比例他花的时间
整单默认选一次,三选一百分之九十以上几秒
品类例外勾一两个品类生鲜、婴幼儿、过敏相关十几秒
单件标记给个别商品打一个标通常不超过五件一件几秒
自由说明写一句话看他愿不愿意愿意写的人自己会写

这个结构的关键不在于层数,在于它把用户的注意力从“每一件都要想一遍”变成了“只有几件需要想”。四十多件里真正有强偏好的通常不到五件,而现在的设计要求他对所有件平均用力。

默认值该倒向哪一边

整单默认那一档只有三个可能:允许替换、不允许替换、缺货就退款。选哪个当默认,这件事的分量比它看上去大得多。

站在站点这一侧,默认允许替换显然更划算——订单金额保住了,履约率好看,缺货不至于变成整单缩水。站在用户这一侧,默认允许替换意味着他什么都不做就把决定权交出去了。

这个开关天然是双向的,但界面只做了一个方向:站点想的是“缺货了我给你换一个,别让这单黄了”,用户想的是“我要的是这个,别给我拿那个”。同一个勾选框,一边是止损,一边是设防,而它的默认值只能倒向其中一边。

这跟行业标准把多数成年人算成大码那一篇里的默认值问题是同一族,但方向正好相反:那边的默认值是用户不认领任何标签就被归进常规码,是一次身份判断;这边的默认值是用户不表态就交出执行权,是一次授权转移。前者错了他被分错类,后者错了他收到别的东西。

那么到底该选哪个

务实的答案是:默认允许替换,但必须配一条通知。

不配通知的默认允许,本质上是拿用户的信任额度做抵押去保这一单的金额,而且这笔抵押不记在任何账上。配了通知之后性质就变了——你依然默认帮他换,但换完立刻告诉他,他可以在送达前点一下拒收。

这是整篇文章里性价比最高的一个组合:默认值不动,只补一条通知。既没有损失订单金额,又把单向授权改成了双向

三选一的措辞,比选项本身更影响结果

这三个选项怎么写,直接决定了用户会选哪个。常见的写法是“允许替换/不允许替换/缺货退款”,这套措辞有个隐患:不允许替换和缺货退款,在用户读来是同一件事,于是三选一实际上变成了二选一,而多出来那个选项只是在增加阅读负担

改成描述结果会清楚很多:换一个最接近的给我/这一件就别送了,别的照送/这一件没有的话整单都别送了。三句话对应三种完全不同的后果,用户读完就知道自己在选什么

第三个选项看着极端,但它真实存在——用户买一整套食材做一道菜,缺了主料,别的送来也没用。这一类订单占比很小,可一旦处理错,用户收到的是一堆没法用的东西,而这种体验的杀伤力远超过一次普通替换

还有一个更省事的口子:让他先说不能换什么

比逐件设置更轻的一个做法,是在结账页加一个可选的整单输入框,提示语写得具体一点,比如“有哪些东西是绝对不能替换的,可以写在这里”。

这个框的填写率不会高,通常两成以内。但它的价值不在覆盖率:愿意花时间写这一句的人,正好就是替换出事之后最容易流失的那一批。你用一个输入框,把最贵的那部分风险单独识别了出来

而且这一句话是纯文本,不需要建模、不需要枚举、不需要对齐任何字段。它唯一的要求是拣货那一端能看到——而这恰恰是它最容易失败的地方:很多站收了这句话,存进了订单备注,然后拣货系统压根不显示订单备注

这个框的位置比它的措辞更重要

补一句实操:这个说明框千万别放在结账的最后一步,跟发票信息、优惠券挤在一起。那个位置上用户已经进入了“赶紧付完”的状态,任何需要动脑子写字的东西都会被跳过

比较好的位置是选完配送时段之后、进入支付之前那一屏。用户刚刚做完一个跟履约有关的决定,脑子还在这个话题上,这时候问他“有什么绝对不能换的吗”是顺的。

问一个问题的最佳时机,是用户刚刚想过相关的事情那一刻。这条在表单设计里是通用的,只是很少有人按它来排字段顺序——多数表单的顺序是按后端需要的处理顺序排的

验收只需要一个动作

这一节所有的改动,验收方式都一样:自己下一单,在备注里写一句只有人能理解的话,然后去仓库那台设备上看它出不出现

这个动作五分钟能做完,但它跨了三个系统——前端、订单中心、仓储作业。保哥见过的情况是,前两个都存对了,第三个的界面上根本没有这个字段的位置,因为那个界面是三年前上的,当时还没有这个需求。

凡是需要跨系统传递的用户输入,都要用这种端到端的方式验一次,不能只验自己那一段。每一段的负责人都会告诉你“我这边是对的”,而他们说的全是实话。

如果非要做逐件,至少别让他从零开始想

有些站的品类结构确实需要逐件设置,比如生鲜占比极高、单价又不低的那种。这种情况下也有办法把成本压下来:不要给用户一个空的输入框,给他两三个已经算好的候选

候选从哪来?三个来源都是现成的:同品牌的其他规格、同品类里销量最高的两个、这个用户自己以前买过的同类商品。第三个来源的效果最好,因为它本身就是他的选择,只是被你按时间存过一遍

但这里有个反例值得记住:候选给多了反而更糟。CVS那次测试里,站点只给了两个自己选定的替代品,用户的反应是强烈的不满——她的原话大意是,我不喜欢替换是这样做的,这是整个流程里我最讨厌的一环,应该在购物车里做,然后给我建议,如果我不喜欢那些建议,还得让我自己挑。

所以候选列表的正确形态是“给建议,但留一个自己挑的出口”。只给建议不给出口,用户读到的信息是你替我圈了范围;给了出口就变成你帮我省了力气,而两者的界面差别只是多一个搜索框

这个分寸跟购物车里推错一次配件,用户就不再相信你这个站的任何一个推荐位那篇说的是同一件事:系统替用户做的每一次预判,都在消耗一个额度,推准了额度回升,推错了额度归零

他选中的那个配送时段,为什么到结账才说没了?

时段是一种库存,而且是最难缠的那种:商品缺货还能等补货,今天的时段过去就是过去了。

一个测试记录:走到结账才发现今天没时段了

Baymard在ALDI的移动站上记下了这么一段。用户从购物车往前走,购物车上没有显示任何履约信息,等她走到下一步才发现,她选的那个门店当天已经没有可用的配送时段了。

页面上写的是:请明天再试。

她的原话带着一点无奈:哦,没有可用时段了,真糟糕……上面说请明天再试,所以你还不能选一个未来的时段,只能选今天的。

两件事同时出错。第一,时段的可用性信息出现得太晚,购物车这一屏完全没提;第二,时段这个东西居然不能预约——今天满了就是满了,不能往后订。

时段是一种库存,而且是最难缠的那种

把配送时段当成一种库存来看,很多事情就顺了。它有容量,会被抢完,会随时间变化。但它跟商品库存有三个致命的不同。

对比项商品库存配送时段
卖光了怎么办可以等补货今天过去了就永远没了
页面上怎么显示商品页明写缺货常常要走到结账才知道
用户什么时候关心看商品的时候加满一车之后
耗尽的速度按天或按周下午三四点集中蒸发
能不能预约预售、缺货预订都成熟很多站压根不支持

第一行是关键:商品缺货用户还能等,时段没了不能等。你告诉他请明天再试,可他今天要吃饭。这两句话之间的落差,就是这一屏的全部问题。

还有一层:时段的稀缺不是均匀分布的

把时段当库存看还有一个推论:它的稀缺程度在一天之内、一周之内都不一样,而这件事页面上从来不说。

周五傍晚和周日上午的时段最紧张,工作日下午最松。用户不知道这个规律,于是他每次来都要重新赌一次;而站点完全知道,因为排班表就是照这个规律排的

能做的事情很简单:在时段选择器上把紧俏程度标出来,或者干脆把最容易约到的那几个时段往前排。这跟机票和酒店那套价格日历是同一个思路,只是生鲜这边通常不需要动价格,光是把可得性说清楚就已经解决大半

更省事的一步是把“下次想约周日上午就要提前到周五”这种话直接写出来。用户不反感规则,他反感的是每次都要靠试错才能发现规则。

信息出现得晚,代价按已投入的时间算

这里有一条通用的判断:一个约束条件出现得越晚,它的代价越高,而代价的大小等于用户在它之前已经投入的工作量

时段这件事把这条判断推到了极端。用户为了走到结账,往购物车里加了四五十件商品,可能花了二十分钟。这二十分钟全都建立在一个从未被验证过的假设上:今天有时段可送

而验证这个假设的成本极低——时段的可用情况是站点自己的数据,随时都能查。它之所以出现在最后,纯粹是因为流程是按后端的处理顺序排的,不是按用户的风险顺序排的。

三个位置,越早越好

时段信息应该出现在三个地方,而多数站只做了最后一个。

第一个位置是首页或者顶部条:今天还有几个时段,最早能送到什么时候。这句话对新用户尤其重要,因为他还在判断这个站能不能解决他今天的问题。

第二个位置是购物车:把已选的履约方式、门店和时段直接显示出来,别让用户猜。ALDI那一屏之所以出事,就是购物车对履约信息只字未提。

第三个位置才是结账。如果一个用户是在结账才第一次看到时段问题,那么前面两个位置都失职了

时段耗尽有一条很陡的曲线,而它每天都长一样

把一周里每天最后一个可选时段消失的钟点画出来,会得到一条相当稳定的曲线,工作日和周末各一条形状。这个数不需要埋点,时段表里就有。

这条曲线的用处很直接:它告诉你几点之后进站的用户已经不可能当天下单了。而这批用户在你的报表里跟别人长得一模一样——他们照样浏览、照样加购,只是在最后一步走掉

知道这个钟点之后能做的事情立刻具体起来:那个点之后进站的用户,首页顶栏直接换成明天最早的时段;广告投放的时段分配可以按这条曲线调;甚至可以把“今天还剩两个时段”这句话做成一个真实的紧迫感提示,而不是那种编出来的倒计时

顺带说,这是极少数可以正当使用稀缺提示的场景之一——因为它确实是真的,而且用户第二天来验证的时候发现你没骗他,这个提示的可信度反而会被强化

不能预约未来时段,是一个产品决定不是技术限制

请明天再试这句话背后,是一个把时段容量按天开放的设计。今天的时段今天放,明天的明天放。

这么做有它的道理,主要是运力排班的不确定性——明天有几个骑手能上,今天下午才定得下来。但它把不确定性完整地转嫁给了用户:站点自己不想承担预估风险,于是让用户每天早上来碰运气

折中做法不难想:开放一部分明后天的时段,数量保守一点,标注上“可调整”。关键不在于放多少,在于让用户能把这件事从待办清单上划掉。他真正受不了的不是等,是不知道要等多久、也没法安排。

预约这件事还有一个用户自己不会说的诉求

用户要的往往不是“我现在就把明天的时段定下来”,而是“我想知道明天有没有”。这两件事的实现难度差得很远。

只要在时段选择器上把明后两天的容量情况显示出来——哪怕明确标注为预估、不接受预约,也已经解决了大半问题。他要的是能不能安排,不是能不能锁定。

这一步的成本几乎为零,因为那些数字你排班的时候本来就算过一遍。把内部已经存在的一个估算值显示给用户,是这类功能里最常被忽略的一档改造:它不产生新数据,只是把已有的数据挪了个位置

这一屏还藏着一个SEO口子

顺带说一件跟搜索有关的事,因为它经常被漏掉。很多生鲜站把“配送区域和时段”这件事只做在应用内,网上没有任何一个可以被搜索到的页面。

而用户实际在搜的是“某某区域 生鲜配送 几点前下单”这类词。这类词的搜索意图极其明确,转化路径极短,而它需要的只是一个能被抓到的静态页面,写清楚覆盖区域、时段规则和截单时间

做法跟DTC配送政策页怎么写那篇是一个思路:把一条本来藏在流程里的规则,单独做成一个页面,它同时解决了下单前的疑虑和一批长尾词。区别在于生鲜的时段规则变化更频繁,所以这个页面要做成能从后台读数的,不能手写死。

这类页面有一个容易做坏的地方

做成动态读数之后,很容易走到另一个极端:页面上直接显示“今天还剩3个时段”这种实时数字。对用户是好事,对抓取程序是灾难——同一个地址每次抓到的内容都不一样,而且抓到的那个数字在被索引之前就已经过期了

稳妥的分法是:规则写在页面上(几点截单、哪几个时段段位、覆盖哪些邮编),实时余量放在页面上但不进结构化数据,也别写进标题和描述里。规则部分几个月才变一次,是这个页面能被稳定索引的那一半。

这跟电商sitemap怎么做里关于lastmod诚实度的讨论是同一个道理:页面上哪一部分是稳定的、哪一部分是易变的,这件事你自己得先分清楚,然后才轮到告诉搜索引擎

点了更改却改不了履约方式,问题出在哪一层?

不是文案问题。履约方式在你的数据库里挂在订单上,在用户脑子里跟着购物车走,两个层级的落差压在一个按钮的两个字上。

点了“更改”,改到的不是他想改的那件事

Baymard在Stop & Shop的移动站上记了一段。用户点了购物车顶部的“更改”,她的原意是从自提改成配送。她说:我下意识觉得应该就在这个“更改”按钮这里,可它给的全是别的自提点……看起来没有办法做这件事。

那个按钮能改的是自提的时间和地点,改不了履约方式本身。

这个错误特别典型,因为它不是用户理解力的问题。“更改”这两个字在这一屏上同时可能指两件事,而按钮上没有第二个词来区分它们。用户按照最重要的那个含义去理解,结果拿到了次要的那个。

履约方式在你的库里是订单级的,在他脑子里是购物车级的

往下挖一层,这不是文案问题,是层级不一致。

在数据模型里,履约方式通常挂在订单上:一个订单要么自提要么配送,选定之后一整单跟着走。这个设计干净、好结算、好排班。

在用户脑子里,履约方式是他这一次逛这个站的一个背景设定,跟着购物车走,随时可以改主意。他不认为自己“提交过一个订单属性”,他认为自己“选了个送法”,而选择当然是可以重选的

两个层级之间的落差,最后全压在一个按钮的两个字上。

更严重的一种:一个购物车里混着两种履约方式

Baymard还记了另一个更狠的场景。有用户花了二十多分钟往购物车里加东西,最后才发现车里混着两类商品——一部分是预留给自提的,另一部分要走快递、几天之后才到。他只能退回去重做一遍。

这一段值得抄给任何一个做混合业态的团队看。购物车不是同质的,履约方式在这类站上其实是商品级属性,而界面把它当成了订单级属性在展示

混合型的生鲜站尤其容易踩:站上既有本地仓的生鲜,也有中心仓发的日用品,两者的履约路径完全不同。用户不知道这件事,因为商品列表页上它们长得一模一样。

更早一点看,问题在履约选择器本身

再往上游走一步会发现,这个“更改”按钮之所以指代不清,是因为站点从一开始就没有一个统一的履约方式选择器。

Baymard另有一条关于履约方式选择器的基准结论50%的站没有把全部履约选项放进同一个选择器界面里。自提在一个地方选,配送在另一个地方选,某些站的当日达甚至藏在结账的第三步。用户想比较两种方式的时间和费用,得来回切换。

把所有履约方式并列在同一个界面上,本身就是一次说明:它告诉用户这个站一共提供几种送法,各自要多久、多少钱。而分散在各处的做法,等于让用户自己去拼一张他从没见过的地图

这也解释了那个“更改”按钮的处境:当履约方式没有一个统一的入口时,“更改”这个词就只能指它旁边那一小块内容,因为整体压根不存在一个可以被更改的对象

三个改法,成本从低到高

最低成本的做法是在列表页和商品页上给每件商品标一个履约标签:今天可送、次日达、快递三到五天。把商品级的差异在商品级的位置上说出来,这是最符合直觉也最省事的一条

中等成本的做法是在购物车里分组显示:这几件今天送到,这几件周四快递到。分组本身就是一次说明,用户不用读任何文字也能看懂。

最高成本的做法才是允许一个订单拆成多个履约批次并分别选时段,这需要动订单模型,通常要排一个大版本。

这三档的顺序不能倒过来。见过团队直接上第三档,做了半年,上线之后发现前两档没做,用户还是在购物车里被同一件事绊倒——他们从来没意识到自己车里有两类东西

分组显示还顺手解决了另一件事

中间那档的分组显示值得多说一句,因为它的收益不止于“看得懂”。

购物车一旦按履约方式分了组,每一组下面就自然有了自己的小计、自己的起送门槛、自己的时段。而这三样东西原本是混在一起算的,混在一起算的结果是用户永远搞不清楚为什么加了一件东西之后运费变了

分组之后这些数字各归各位,用户看一眼就知道差多少能免邮。一个纯粹为了表达清楚而做的改动,顺手把一个计算透明度的问题也解决了,这种情况在信息设计里其实很常见

运费规则本身怎么配才不亏钱又不赶客,WooCommerce运费怎么配才不亏钱不丢单那篇按配送区域和费率类别算过一轮,可以对照着看。

顺便修一下按钮上的字

回到最开始那个“更改”。这类按钮的写法有一条很土但很管用的规则:把宾语写进按钮里

不写“更改”,写“更改自提时间”;不写“编辑”,写“编辑收货地址”。多几个字,在移动端确实占地方,但它换来的是这个按钮再也不会被误解。

如果确实放不下,那就退一步:把用户最可能想改的那件事单独做成一个入口,而不是把所有的改都塞进同一个词里。在这一屏上,用户最想改的是履约方式,那就让它有自己的位置。

这个原则跟你的后端一清二楚用户错在哪里,页面上却只剩下四个字那篇讲的是同一件事的两端:那边是系统知道得多、说得少,这边是界面能指的对象多、词只给了一个。两种情况下用户都得靠猜,而猜错的成本全归他。

混合履约还牵着一条SEO上的线

履约方式是商品级属性这件事,往搜索那边延伸还有一层。前面提到Google的商品数据规范里有一条很硬的要求:落地页必须明确写出任何配送限制,例如仅限门店自提

紧接着还有一条更硬的:商品必须是可配送的,仅限门店自提目前不被支持,只有阿根廷和智利是例外。也就是说,如果你站上有一批商品只能自提,它们本来就不该被提交进商品数据。

这一条在混合业态的站上经常被违反,而且违反得很隐蔽:商品数据是按整个目录批量导出的,导出脚本不认得“这个SKU只在门店卖”这件事,因为那是仓储侧的一个标记,而不是商品主数据里的字段

结果就是这批商品在广告和免费商品列表里正常展示,用户点进来才发现送不到他那儿。这跟产品feed到底该谁管那篇讲的归属问题是同一个根:商品数据这份东西的字段来源横跨三四个系统,而维护它的人通常只有一个部门的权限

上次买过的那罐,为什么要翻到购物车最底下才找得到?

订单是按时间切的,复购需要按商品切。同一批数据两种切法,而站点只提供了其中一种。

用户为了买一罐上次买过的东西,跑到了购物车底部

Baymard记的这一段很有画面感。一位用户在Target的移动应用上想把以前买过的一件商品加进购物车,她的做法是:打开购物车,一直拉到最底下,在“再买一次”里横向滑动,直到找到那件东西。

她的原话是:如果我知道自己以前买过,我会到购物车这里来。

另一位用户在Kroger的应用上想到了“购买历史”这个页面,但立刻放弃了。她说:说实话,如果找一件特别少见的东西,我大概会去看订单历史……但我不会那么做,那实在是太多次点击了,因为我还得记得它在哪一单里面。

订单是按时间切的,复购需要按商品切

后面那句话点出了整件事的结构性原因:订单历史是按时间组织的,而复购需要按商品组织。同一批数据,两种切法,而站点只提供了其中一种

用户脑子里的问题是“我上次买的那个牌子的燕麦叫什么”,订单历史能回答的是“我三月十二号那单买了什么”。要用后者回答前者,用户得先想起日期——而他记得住牌子记不住日期,否则他压根不用来查

解法本身不复杂:把用户买过的所有商品去重,按最近购买时间或者购买次数排序,做成一个独立的列表,支持在里面搜索。数据是现成的,就在订单表里。

复购列表要按什么排,答案不是最近购买时间

做这个列表最容易的排序方式是按最近购买时间倒序,但它不是最好的。用户上周买过的东西这周不一定要买——牙膏两个月一支,牛奶一周两瓶,两者在“最近购买”这个维度上没有可比性

更贴合的排序是按购买间隔推算:这件商品他平均多少天买一次,距离上次买过去了多少天,快到周期的排前面。这个算法听着复杂,其实两行SQL的事,而且它带来的体验差别很明显——列表打开就是他今天真正需要补的那批

做不了推算的话,退一步按购买次数排也比按时间排好。买过八次的东西一定比买过一次的更值得放在前面,这个判断不需要任何模型

这个品类里,复购是主路径不是快捷方式

在别的品类里,“再买一次”是一个锦上添花的功能。生鲜不是。

Baymard的观察是:用户在生鲜站上的使用频率远高于服装或者电子产品站,因为生鲜每周都要订,而这带来了这个品类特有的长期忠诚度潜力。测试里那些之前下过单的用户,严重依赖能让他们重新购买过往商品的功能,包括首页上的入口和搜索里的标记。

Amazon Whole Foods的应用把“再买一次”放在首页首屏的大部分位置,测试里有用户一进来就说:我先从我的“再买一次”开始。Instacart的移动站允许用户直接在首页的过往购买上点加号,还能在那里调数量、删商品,不用进商品页也不用进购物车。

这两个例子的共同点是位置:它们把复购入口放在了用户开始逛之前,而不是逛完之后

一个对做SEO的人很不舒服的数字

这一节还有一个数据值得单独拎出来:Baymard的生鲜研究显示,只有一半的生鲜用户访问过商品页,其余的人直接从首页、搜索结果或者列表页加购。

这个比例对做电商SEO的人来说有点扎心,因为商品页通常是投入最多的那一类页面——结构化数据、图片、评论、描述,力气全在那儿。而在这个品类里,一半的人根本不去

Baymard给的解释很合理:他们要买的东西自己早就熟悉,不需要商品页提供的那种详细程度,他们要的是效率。

这条观察带来两个直接的动作。第一,列表页上必须有足够做决定的信息——规格、单位价格、库存状态、履约标签,因为一半的决定是在这一屏做出的。第二,跟缺货和替换有关的一切提示,不能只写在商品页上,否则有一半用户永远看不到。

那商品页的SEO工作要不要减?

不要减,但要改口径。这个数字说的是站内行为,不是搜索入口。用户不进商品页,指的是他已经在你站上、正在建购物车的时候不进;而他从搜索引擎点进来的那个落地页,绝大多数情况下就是商品页

两件事的差别很关键:商品页在这个品类里的角色,从“逛的时候看的那一页”变成了“从外面进来的第一页”。它服务的不是老客户的效率,是新客户的第一印象

按这个定位反推,商品页上该加强的东西就变了:结构化数据、清晰的库存与配送说明、一眼能看懂的规格和单位价格,这些都是给第一次来的人和抓取程序看的。而那些为了提升站内浏览深度做的相关推荐、搭配购买,在这个品类里的价值要打个折扣,因为老客户根本不走这条路

顺带说一句,用户扫完一整屏商品一个都没点开那篇算过列表页的信息不足会怎么静默流失,那篇的结论在这个品类里要再加重一档:别的品类里列表页信息不够,用户还会点进商品页去看;这里他直接就不买了

列表页那个每单位价格,正好也在这一屏

说到列表页要给足信息,有一个字段在生鲜品类里的重要性远高于别处:每单位价格。

Baymard提到Peapod用每一百平方英尺的价格,帮用户比较不同规格的纸巾。同一件商品有大包小包三四种规格,价格互相之间没法直接比,用户要么心算要么放弃。

这个字段的计算口径和合规要求另有讲究,商品列表页上那个每千克价格那一篇专门算过一轮,这里就不重复。只补一句跟本文有关的:单位价格是列表页上极少数能替代商品页的信息之一,而它恰好长在那一半用户唯一会看的那一屏上

复购列表还顺手解决了替换的一半问题

最后把这一节接回主线。一个做得好的复购列表,会让替换这件事的伤害小一截,原因不太直观。

用户之所以对被换掉的商品反应大,很大一部分是因为他买的是“习惯”——同一个牌子买了两年,换一个他就得重新适应。而复购列表恰好是站点手上最清楚的一份习惯记录:他连续买了六次的那个牌子,就是绝对不能随便换的那一件

这份数据你已经有了,不需要用户填任何东西。把“连续购买次数超过某个阈值”的商品自动标成高敏感,缺货时优先走通知而不是直接替换,这一条规则大概是整篇文章里投入产出比最高的一个改动

缺货这个状态,页面、商品数据和抓取程序看到的是同一个吗?

Google要求四个地方口径一致,而它在写这句话的时候把四处记成了三处。

Google要求四个地方口径一致,而它自己在这句话里数漏了一个

Google商品数据规范里关于availability属性的那一页有一条硬要求,原文要求商品的库存状态在落地页、结构化数据、结账页和数据源之间保持一致,任何一处对不上都会触发商品被拒批。

有意思的是,这句话列了四个地方,紧接着的半句写的却是“这三处必须匹配”。规范自己在数的时候漏了一个。这不是抠字眼——如果连写规范的人都会把四处记成三处,那么一个跨了前端、商品数据和仓储三个团队的站,四处口径能对上的概率有多大,心里大概有数了

保哥带团队盘过几次这四列,还没遇到过完全对得上的站。最常见的形态是:落地页写着有货,数据源是三小时前导出的,结构化数据里那个字段从上线那天起就写死成InStock,结账页只在提交订单的一瞬间才去查真实库存。

12个格子映射到4个格子,有两个无处可去

再往下一层看这个字段本身。schema.org的ItemAvailability枚举一共12个成员:BackOrderDiscontinuedInStockInStoreOnlyLimitedAvailabilityMadeToOrderOnlineOnlyOutOfStockPreOrderPreSaleReservedSoldOut

Google商品数据这一侧只有4个值:in_stockout_of_stockpreorderbackorder(另有一个仅用于车辆广告的build_to_order)。官方给了一张映射表:

Google的值吸收了schema.org的哪几个
in_stockInStock、LimitedAvailability、OnlineOnly
out_of_stockDiscontinued、InStoreOnly、OutOfStock、SoldOut
preorderPreOrder、PreSale
backorderBackOrder

数一下会发现,12个成员里被映射表点名的只有10个。MadeToOrderReserved这两个,在这张表上没有位置。

压缩不是均匀发生的,它专挑一类值下手

但真正值得停下来的不是格数差多少,是被合并的那几个值恰好是哪几个

in_stock那一格:InStockLimitedAvailability被压成了同一个值。前者是“有货”,后者是“库存有限”。

而“库存有限”正是本文整篇在讨论的那个状态——它今天有、明天可能没有,是所有状态里最容易在用户下单之后变成缺货的一个。压缩把最不确定的那个状态,藏进了最确定的那一格

再看Reserved无处可去这件事。已被预留恰恰是自提业务里最常见的中间态:用户下了单,商品还在货架上,但已经归他了。这个品类里天天在发生的状态,在Google的商品数据里没有对应的词

所以这件事的完整形状是:用户那一侧的意图被压成一个布尔值,机器这一侧的库存状态被压成四个值。同一种降维在链路的两端各发生一次,两次都被当成合理的简化,两次都把最需要区分的那类情形合并掉了

落地页那几条硬要求,比看上去严

顺着这份规范往下读,落地页那一段的要求也值得逐条对一遍,因为它比多数人印象里严格。

状态落地页必须做到
有货购买按钮必须是可用的
缺货写明“售罄”这类文字,或者把按钮禁用置灰
多变体页面可以在选择网格里单独禁用不可用的规格
预订或缺货预订页面必须显示预计发货日期
任何配送限制必须在页面上明确写出,例如“仅限门店自提”

最后一行对生鲜和本地零售站是个直接的坑:规范还写明,商品必须是可配送的,仅限门店自提目前不被支持(阿根廷和智利除外)。也就是说,那些只做自提的商品,本来就不该出现在商品数据里。

另外两个值的用法也常被搞混:preorder只用于尚未发售的新品,已经在卖但暂时断货、你仍接单的商品应该用backorder。两者都必须提供availability_date,而且这个日期要在落地页上可见。

抓取程序不会替用户选门店

还有一层是这个品类独有的,一般电商的技术文档里找不到:同一个商品地址,在不同门店、不同配送区域下有没有货、卖多少钱,是不一样的

Google的文档里最接近这个场景的是关于抓取语区自适应页面的那一份。它说得很明确:如果站点会根据访客所在国家或语言偏好返回不同内容,Google可能不会抓取、索引或排名所有语区的内容;原因是Googlebot的默认IP看上去在美国,而且它发出的HTTP请求不设置Accept-Language请求头。文档还提到Googlebot对所有抓取配置使用同一个用户代理字符串。

把这段话翻译到生鲜站的处境上:Googlebot不会选门店,不会填邮编,不会带着你的门店cookie。它看到的永远是那个默认状态,而那个默认状态跟你绝大多数真实用户看到的都不一样

需要说清楚的是,这跟按IP自动跳转语言版本正在让你的国际站半数页面进不了索引那篇讲的不是一回事。那边的问题是跳转——服务器把抓取程序弹到了别的地址;这边根本不跳转,地址不变,返回200,只是内容换了一套。前者在日志里看得见,后者在日志里完全正常

那这一层到底该怎么处理

务实的做法是分三层,跟Google对语区问题给的建议同一个思路:能拆成独立地址的就拆。

第一层,把商品页的默认状态设成全网可售的那一套:价格用全国统一价或者最常见的那一档,库存状态按仓库总库存写,别按用户当前门店写。抓取程序拿到的这一份,至少是全站范围内成立的。

第二层,把门店维度做成独立地址,比如给每个门店或者配送区域一个可以直接访问的页面,写清楚这个点覆盖哪些区域、有哪些时段、常备哪些品类。这类页面天然带本地词,是这个品类里最容易做的一批长尾。

第三层,结构化数据里别写你自己都不确定的东西。如果库存真的按门店变化而你只能给一个值,那就给那个在最大范围内成立的值,别让富摘要上写着有货、用户点进来发现他那个区送不了——这种不一致除了会触发拒批,还会消耗掉一次很贵的点击。

门店页那一层,比想象中值钱

第二层那个“把门店维度做成独立地址”值得单独说两句,因为它经常被当成一个可有可无的附属页面草草做完。

这类页面的搜索价值来自一个很朴素的事实:用户在找生鲜配送的时候,搜的几乎全是带地名的词。而带地名的词竞争程度远低于品类词,转化意图又高得多

页面上该有的东西也不复杂:覆盖的区域清单、当前的时段规则、截单时间、起送门槛、这个点常备的品类、地址和联系方式。如果是实体门店,再加上营业时间和一张能看清位置的地图

要避开的坑是别把这些页面做成同一个模板换个地名。电商重复内容怎么治那篇里列过八类成因,批量生成的地区页正是最典型的一类。判断标准很直接:如果一个页面除了地名之外的内容跟另一个页面完全一样,那它就不该单独存在

本地这一侧还牵着商家资料那条线,本地SEO卡在地图前列之外那篇讲的实体识别问题在这里同样适用——门店页和商家资料上的名称、地址、营业时间必须一个字都不差,这件事非常枯燥,也非常有效

一个可以今天就跑的自查

这一节的所有内容可以压缩成一次五分钟的自查。挑三个商品,把四列数字并排写下来:

第一列,用curl拉一次商品页源码,看HTML里写的库存状态和购买按钮的状态;第二列,从后台导出商品数据文件,找到同一个商品的availability;第三列,用富媒体测试工具跑一次这个地址,看结构化数据里的availability;第四列,走一次结账,看提交之前系统认为它有没有货。

这四列如果不一致,问题不在于哪一列错了,在于这四列从来没有被同一个人同时看过。而它们分别归属于前端、商品数据运营、SEO和后端四个角色,谁都能诚实地说自己那一列是对的。

做完这次自查还有一个附带动作值得顺手做掉:把这个对照写成一个每周跑一次的脚本,抽样二十个商品,四列不一致就报出来。理由跟做站点地图体检一样——站点地图里抽了585条网址,48条是坏的,而生成它的程序一次都没报错那篇的教训在这里完全适用:生成数据的程序不会报错,因为它每一步都按代码执行了;错的是代码里那个假设,而假设不会自己举手

再往前一步:AI购物那一侧要的是同一份数据

还有一个正在变得重要的收件人。用户越来越多地在对话式的界面里问“帮我买这个”,而回答这个问题的程序读的是你的商品数据和结构化数据,不是你的页面截图。

这一侧对库存状态的敏感度比搜索更高。搜索里显示一个过期的有货状态,代价是一次浪费的点击;在代购型的场景里,一个错误的库存状态可能直接变成一次失败的下单

这件事的完整清单在你的独立站在AI购物代理眼里及格吗那份自查表里,本文只补一条跟缺货有关的:四列口径一致这件事,从“避免商品被拒批”升级成了“别让程序替用户下一个注定失败的单”。同一份数据,两个时代,要求的严格程度不一样

不加一行埋点先算哪几个数,改完之后哪个数会骗你?

五个数全在你已经存了很多年的东西里。而一次做得很规矩的改造,可能会在一个谁都没想到的入口上失血。

五个数,全都来自你已经存了很多年的东西

这类问题最大的障碍不是不会改,是没人能证明它值得改。下面五个数一行埋点都不用加,数据全在订单表、客服系统和搜索控制台里。

指标怎么算它回答什么口径要小心什么
替换发生率发生过替换的订单数除以总订单数,按品类切这件事在你站上的规模整单缺货退款不能算进来,那是另一回事
替换后第30天回访率发生替换的用户与同期未发生的对比它到底伤不伤忠诚度要剔除首单用户,他们本来就流失得快
授权覆盖率做过任何一种替换设置的订单占比那个开关有没有被找到默认值不算,只算主动动过的
时段耗尽时刻每天最后一个可选时段消失的钟点,画一周用户几点之后来就白来了按门店分开画,合起来看没有意义
那类问句的工单数客服记录里搜“没货怎么办”这类问法下单前有多少人在担心下单前和下单后的问法要分开数

五个数里第二个最有说服力,也最容易被推翻,所以口径要提前说死。剔除首单用户这一条不能省——首单用户的自然流失率本来就高,不剔除的话结论会被质疑,而这种质疑一旦出现,整个项目就得重新排期

四格交叉:替换发生率乘以复购频次

五个数单看都有解释空间,交叉起来才有判断力。把商品按替换发生率和复购频次各切两档,得到四格。

高替换、高复购那一格是要先动的:用户经常买、又经常被换掉,这一格里的每一次替换都在消耗一个本来最稳的客户。牛奶、鸡蛋、面包、酸奶多半落在这里。

高替换、低复购那一格优先级低,用户对这类商品本来就没有强偏好。低替换、高复购那一格说明你这几个品供应稳定,不用管。

低替换、低复购那一格通常是长尾,可以直接忽略——但要小心一种情况:低替换有可能是因为它压根卖不动,而不是因为它库存好。看一眼销量就能分辨,这个错判在数据上很隐蔽

有一个数不建议算

不建议算“平均每单被替换了几件”。

大部分订单一件都没被换,少数订单被换了五六件,平均下来是零点几件——这个数字不描述任何一个真实用户,而且它对改造极不敏感:你把最严重的那批订单修好了,平均值也只动一点点

更有用的是分布:被换了三件以上的订单占多少,这些订单里的用户后来还回不回来。凡是遇到长尾极不均匀的现象,第一反应就该是放弃平均值去看形状,这条在别的指标上同样成立

一次失手复盘:修好了替换,却在另一个入口上失血

说一个保哥自己踩过的。客户是一个东南亚市场的本地生鲜配送站,做蔬果肉蛋和日用品,客单价折合十几到三十美元,履约靠三个本地前置仓,用户以家庭主妇和上班族为主。

那次改造做得很规矩:结账页的替代品设置提前到购物车做提示、连续购买超过四次的商品自动标高敏感、替换发生时发一条短信带拒收链接、订单详情页保留下单和实收两行、时段信息提到首页顶栏。

六周之后数据很好看:替换后第30天回访率从原来的低于站均11个百分点收窄到3个百分点,授权覆盖率从不到一成涨到三成七,“没货怎么办”的售前问询降了一半多。

第九周开始,自然搜索的商品页展示量连续掉,两个月掉了四成

问题出在一个谁都没想到会有影响的改动上

排查了很久才找到。为了让用户一进站就看到自己那个前置仓的真实库存,前端把商品页的库存状态改成了根据用户所在配送区域动态渲染的,没选区域的访客看到的是一个“请先选择配送地址”的占位。

这个改动在人这一侧完全成立——用户一进来第一件事就是填地址,填完什么都正常。而Googlebot不会填地址,于是它抓到的每一个商品页,购买按钮都是禁用状态,库存位置写的是那句占位文案

结构化数据里的availability跟着页面状态走,也变成了OutOfStock。商品数据文件那一侧倒是正常的,于是形成了一个非常标准的落地页与数据源不一致,Merchant Center开始陆续拒批。

四层为什么都没拦住:第一,人肉验收全过,因为测试的人一定会填地址,不填他没法验;第二,改动本身是一次正当的体验优化,评审时的理由是“让用户看到真实库存”,没有任何一个环节说错了话;第三,这个改动的提交记录里没有任何一个词跟SEO有关,所以SEO那边根本没被叫去评审;第四,拒批通知发到了商品数据运营的邮箱,而那个人以为是价格波动引起的老毛病,等下一次全量导出自动恢复

这次的预警形态:报警响了,但响在了另一个人的收件箱里

把这次和以前几次摆在一起看,预警的失效方式每次都不一样。

有几次是根本没有预警:损失以另一项指标变好的形式出现,没有任何异常可以被观察到。这次不是——预警响了,内容也准确,它只是响在了一个不认识这件事的人的收件箱里,而那个人凭经验做出了一个合理的判断

所以这一类的解法不是加监控,是改收件人。同一条拒批通知,发给商品数据运营,他会按经验归类为价格波动;发给做过这个改动的前端,他一眼就知道是自己上周那次提交。

改动后来加了三条:一是任何改变商品页库存渲染方式的提交,必须附一次curl前后对比,由提交的人自己跑;二是Merchant Center的拒批通知同时抄送前端负责人;三是把“未选择配送地址的访客也必须看到一个可售的默认状态”写成断言,跟着构建跑

三个月后展示量回到了改造前的水平并继续往上走。而那次改造在用户侧的收益一直都是真的,从来没有回退过——这也是最麻烦的地方:如果收益是假的,早就有人推翻它了

这次事故还留下一条可以直接抄的验收问句

整件事如果要浓缩成一句可以在评审会上问出口的话,是这句:这次改完之后,一个不会填地址、不会选门店、不带任何cookie的访客,还能不能看到一个可售的商品页?

它之所以没被问出来,不是因为难。curl一次五分钟就有答案。是因为在那间会议室里,所有人心里默认的那个访客都是会填地址的

把这句话贴在商品页相关的评审模板里,成本为零。Nginx配置每次reload都通过,Googlebot每8次抓取却有1次撞在301上那篇里也是同一类问题:所有的检查都通过了,因为检查的人和被影响的对象不是同一种访客

三档投入,按能不能立刻验收排

档位做什么要谁大概多久
第一档购物车加一行提示、按钮补宾语、时段信息提到首页、订单详情保留两行前端一人一周
第二档替换通知加拒收链接、高敏感商品自动标记、备注传到拣货端前端加订单加仓储三到四周
第三档分层授权、履约方式改成商品级、四列口径打通再加SEO与商品数据一个季度

第三档里最花时间的不是技术,是让四个角色在同一张表上对一次数。这件事没法异步做,必须坐到一起,而约齐这四个人本身就要两周。

顺带一提,这三档的排法不是按技术难度,是按能不能立刻验收。第一档的每一项,做完当天打开手机就能确认;第三档的效果要等一个完整的复购周期才看得出来。把不能立刻验收的东西排在前面,是项目半途死掉最常见的死法

三条停手信号

第一条:替换发生率降下来了,但回访率没动。这说明伤害不在替换本身,在别处,继续优化替换是浪费。先去看看是不是配送时效或者商品品质的问题。

第二条:你在给一个交付时间不构成购买动机的品类做这套东西。前面那句判断可以再用一次——如果晚两天送到用户完全无所谓,那你该做的是延后交期,不是替换。

第三条:团队开始争论默认值该不该是“允许替换”。这个争论会开三次会,而它的答案在配了通知之后已经不重要了。争论最激烈的那个细节恰好是配了通知就自动消解的那一个,这通常意味着真正有分歧的问题已经被绕过去了

立项时怎么说

这件事最容易被砍的原因是它没有页面。周会上大家在看转化漏斗,这件事发生在漏斗结束之后。

保哥用过的说法是:这一单的钱已经收到了,货也已经发出去了,我们现在讨论的是要不要在最后一米把它做完。你不是在申请新预算,是在申请别让已经赚到的那笔钱在最后一步漏掉

另外一句也管用:这个品类的用户每周都会来一次,你有五十次机会赢得他,也有五十次机会失去他。别的品类一年才见一两面,这里的每一次履约都是一次续约

第一次会上一定要拉两个人:一个是拣货或者仓储的负责人,他知道现场到底是怎么判断的,而那套判断规则从来没写在任何文档里;另一个是做商品数据的,他知道那四列口径里哪几列是手工维护的,而这决定了第三档是一个季度还是两个季度。

先从哪个品类开刀

如果站上品类很多,不必全线铺开。挑选标准有三条,越靠前越优先。

第一条,复购频次高且替换率高的那批——牛奶、鸡蛋、面包这类。这是前面四格交叉里那个左上角,每一次替换都在消耗一个最稳的客户。

第二条,用户有强品牌偏好的那批——婴幼儿食品、宠物粮、过敏相关、特定饮食习惯的商品。这类东西换错了不只是不高兴,可能直接不能用。宠物粮尤其典型:换牌子要花一周慢慢过渡,随便换一个的结果是狗不吃,而这件事用户会记很久

第三条,客单价高、单件占比大的那批——一整块牛排、一盒进口水果。这类商品被换掉,用户损失的金额感受最明显。

往后放的是价格低、无差别、用户没偏好的东西:白糖、食盐、厨房纸。这一类替换了大概率没人在意,甚至用户根本不会注意到自己收到的是另一个牌子

最后留一条给做SEO的人

这一整篇看下来,SEO在这件事里的位置有点特别:你不是这个流程的负责人,但你是唯一一个每天都在看“外部世界怎么看我们的库存”的角色

商品数据的拒批通知、富媒体测试里的字段、搜索结果上显示的有货还是缺货,这些东西每天从你眼前过。而做替换、做时段、做履约的那几个团队,谁都不会主动来看这些。

所以这件事上最有用的一次贡献,往往不是提一个优化方案,是把那四列数字并排贴出来,发给那四个人。这张表不需要论证,谁看到都立刻明白问题在哪

常见问题解答

缺货替代品的默认值到底该设成允许还是不允许?

建议默认允许替换,但必须同时配一条替换发生时的通知,两者是一套。默认不允许会让缺货直接变成整单缩水,而多数用户其实并不反对被换一件相近的东西。真正让人不舒服的不是被换,是被换了却没人告诉他,等他打开袋子才发现。配上通知之后这个默认值的性质就变了:你依然替他做了决定,但他在收货前有机会知道并且拒收,单向授权变成了双向。如果通知暂时做不了,那就在结账页放一个可选的整单说明框,让用户写下绝对不能替换的东西。填写率不会高,但愿意写的那批人正好是替换出事后最容易流失的。

替代品的选择功能该放在购物车还是结账?

功能放结账是合理的,因为替代逻辑依赖履约点和商品清单,这两样在购物车阶段还没定死;但购物车里必须有一句话告诉用户这个功能存在。Baymard在2022年测Walmart、2026年测CVS,隔了四年两个不同的站,用户都在购物车里翻上翻下找这个开关,找不到,然后开始犹豫要不要继续下单。两个站的功能其实都有,只是都在结账里。所以第一版改动不用动那套依赖关系,只需在购物车靠近结算按钮处写一行。用户在这一步需要的不是功能本身,是这个功能存在这条信息,因为他在判断这个站管不管这件事。

生鲜站的缺货处理为什么不能照搬一般电商那一套?

因为一般电商的缺货解法是拿时间换库存,而生鲜没有这段时间可以换。Baymard建议暂时缺货的商品继续让用户下单、只把交期加长,理由是线上购物天生带一段等待期。这个逻辑在服装和电子产品上完全成立,红裙子晚两天到不影响下个月的婚礼。但一瓶牛奶晚两天到就没有意义了,交付时间不是这一单的成本项,它是这一单存在的理由。所以在这个品类里,替换是缺货处理的主流程而不是附加功能。判断标准可以直接拿去用:先问这个品类的交付时间是不是购买动机本身。

给几十件商品逐件设置替代品,用户真的会做吗?

不会,而且这个设计会直接把人赶走。Baymard的生鲜研究里记录过,有些测试用户面对给50多件商品逐个选替代品,直接被压垮弃站了。逐件设置从任何角度看都更尊重用户,颗粒度更细、意图保留得更完整,它唯一的问题是用户干不动。这里的变量只有一个:购物车长度。别的品类购物车两三件,生鲜站四五十件。可行的做法是把授权做成分层的,整单先给一个默认策略覆盖九成以上商品,再让用户对少数几件打例外标记。四十多件里真正有强偏好的通常不到五件,现在的设计却要求他对每一件平均用力。

怎么在不加埋点的情况下证明这件事值得投入?

有五个数完全不需要埋点,全在订单表、客服系统和搜索控制台里。一是替换发生率,按品类切开看;二是替换后第30天回访率,跟同期没发生替换的订单对比,这个数最有说服力,但要提前说死剔除首单用户的口径;三是授权覆盖率,只统计主动动过设置的订单;四是每天最后一个可选时段消失的钟点,按门店分开画;五是客服记录里下单前问没货怎么办的工单数。把商品按替换发生率和复购频次各切两档,高替换加高复购那一格要先动。不建议算平均每单被换了几件,那个数不描述任何真实用户。

库存状态在结构化数据和商品数据文件里为什么老是对不上?

因为四列分属四个角色,没有人同时看过它们。Google要求库存状态在落地页、结构化数据、结账页和数据源之间一致,任何一处对不上都会触发商品被拒批。常见形态是落地页写着有货、数据源是几小时前导出的、结构化数据里那个字段从上线起就写死。还有一层是枚举压缩:schema.org的ItemAvailability有12个成员,Google商品数据只有4个值,映射时库存有限和有货被合并进了同一个in_stock。自查很简单,挑三个商品,用curl拉源码、导数据文件、跑富媒体测试、走一次结账,四列对一遍。

Googlebot看到的商品页库存,跟真实用户看到的是同一份吗?

多数按门店或配送区域显示库存的站上不是同一份。Google关于语区自适应页面的文档说得很明确:Googlebot的默认IP看上去在美国,而且请求不设置Accept-Language请求头,所以按访客所在地返回不同内容的站可能不会被完整抓取和索引。搬到本地零售的场景就是,Googlebot不会选门店、不会填邮编,它看到的永远是默认状态。这跟按IP自动跳转是两回事:那种情况服务器会把抓取程序弹到别的地址,日志里看得见;这里地址不变、状态码是200,日志里完全正常,所以更难发现。

权威参考资料

分享到
标签
版权声明

本文标题:《他买的是这瓶牛奶,装进袋子的是哪一瓶,由两小时后站在货架前的人决定》

本文链接:https://zhangwenbao.com/grocery-substitution-preauthorization-notification.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交