购买区模块:价格、选项、数量与加购
购买区模块让顾客在商品页确认“我现在选的是什么、多少钱、能不能买、怎么买”。它把价格、变体选项、数量、加购与立即购买、可售状态和购买前必须看到的配送与退换提示放在同一个决策点,而不是零散的按钮与文字。
购买区 = 当前变体 × 价格与规则 × 数量与选项 × 购买动作 × 购买前提示
先确定模块在完成什么任务
- 顾客问题:这个配置多少钱?有没有优惠?能不能现在买?多久到、能不能退?
- 对象层级:商品(product)承载名称、说明与共同属性;变体(variant)承载价格、划线价、单位价、可售状态与数量规则。购买动作必须落在一个具体变体上,商品级信息不能代替变体级事实。
- 进入前已知:商品身份、可选选项、默认或已选变体(可能来自地址参数)、买家市场与币种。
变体切换时媒体的同步归变体媒体;售罄、低库存与到货通知归库存状态与到货通知;加购之后的核对归购物车摘要。购买区只负责把“当前选择”交给这些模块并保持一致。
信息来源与输入
| 输入 | 来源 | 最低要求 |
|---|---|---|
| 标题、简述 | 商品资源;商品概述内容 | 与页面标题一致;不写库存与价格 |
| 价格、划线价 | 变体资源 | 取当前变体;有多个价格时先写“起价”,选定后写该变体价格 |
| 单位价 | 变体资源 | 有单位价格数据才显示,标明单位与基准数量 |
| 选项与选项值 | 商品与变体资源 | 每个选项有名称;不可用组合的表达见状态一节 |
| 数量与规则 | 变体数量规则 | 最小、最大、步长从平台读取 |
| 可售状态 | 平台状态 | 随变体变化,不写成商品级静态文案 |
| 销售计划 | 平台状态 | 计划随变体变化;选择必须进入加购请求 |
| 配送与退换提示 | 配送信息、保证详情内容 | 摘要 + 完整规则入口,且与结账一致 |
| 动作 | 交易动作 | 提交的变体、数量、销售计划与所见一致 |
价格、划线价、可售状态、销售计划与数量规则是运行时事实,不得写进商品描述或静态文案,否则改价后会与购买区矛盾。
价格一致性
购买区里可能同时出现现价、划线价、单位价、销售计划价和折扣后价。逐项区分含义,再决定怎么摆:
- 现价与划线价(compare-at):帮助中心写明划线价必须高于价格才会显示为促销价;两者可显示在商品页与集合页,结账页只显示销售价;用折扣实现的划线展示在商品页需要第三方应用或自定义开发,而自动折扣或折扣码的节省在结账页总是以划线价显示。所以划线价是“商家设置的参考价”,不能被写成“限时折扣”,也不要用来暗示不存在的历史价格;参考价的法规要求需要法务确认。
- 单位价:官方帮助说明单位价会自动显示在商品、集合、购物车与结账页,每个商品或变体只能有一个单位价,且同一单位类型在所有市场保持一致。展示时用平台的单位价格式并检查是否有单位价格测量数据,不自算。
- 销售计划价:订阅或预购的价格来自
selling_plan_allocation,含price、compare_at_price、per_delivery_price、checkout_charge_amount等;必须显示顾客现在要付多少与之后如何付,不能只显示折扣后的单价。 - 起价:
product.price是所有变体中的最低价,price_varies标识价格是否有差异。未选变体时写“起价”,选定后立即换成该变体价格。
标题下、吸底加购栏和快速购买里的价格共用同一份数据,见Sticky Bar。
状态与退化
| 状态 | 处理方式 |
|---|---|
| 零个选项 | 只有默认变体时(has_only_default_variant)不渲染选项控件 |
| 一个或多个选项 | 每个选项独立标签;选中一个后,另一个选项的不可用值给出原因 |
| 未选选项 | 加购按钮说明“请选择颜色”而不是无反应;不要默认选中一个让顾客没注意就买走 |
| 当前变体售罄 | 说明该配置暂时无货,切到有货相邻选项,并提供到货通知入口,见库存状态与到货通知 |
| 数量越界 | 就近说明最小、最大或步长,提交前拦截,不依赖服务端才报错 |
| 超库存 | 加购被拒绝时显示平台返回的原因,不改成“成功” |
| 加载 | 变体切换中价格与按钮同时进入更新状态,禁用提交;迟到的旧响应不得覆盖新选择 |
| 错误 | 错误信息留在购买区,不用会消失的提示,见下文与Toast |
| 过期 | 停留久后加购以平台返回为准;价格或库存已变要说明 |
| 跨市场 | 币种、价格、可售状态和配送提示随市场变化,不显示另一个市场的价格 |
| 无 JavaScript | 选项与数量仍是真实的表单控件,提交走表单,价格随页面刷新更新 |
可选展现与交互
- 选项呈现:少量选项用按钮或色板,多选项或长名称用下拉;具体形态见Horizon 变体选择。
- 提示细节:配送时效、退换条件的完整版放折叠面板或独立页,购买区内只留一行摘要;不要只放进Popover,价格构成、运费、退换期限、库存等关键条件必须直接可见。
- 吸底加购:价格与变体必须与主购买区同源,未选变体或售罄时同步显示同样状态。
- 加购反馈:成功用简短确认,错误留在原位。
“立即购买”与加购不得使用两套变体来源。
页面组合中的位置
购买区通常位于商品页首屏,紧邻媒体区与标题,其后是详情、规格、评价与相关推荐。集合页商品卡与快速购买弹窗可复用同一契约,但要在各自入口核对商品上下文。价格不应藏在需额外点击的位置,文章正文里也不承载完整变体选择。
无障碍与性能
- 每个选项有可见标签或可编程名称(WCAG 2.2 的 3.3.2 Labels or Instructions,A);不可用或已选状态不能只靠颜色区分(1.4.1 Use of Color,A)。
- 自定义单选、按钮组需要暴露名称、角色与已选状态(4.1.2 Name, Role, Value,A)。
- 选项变化不得在没有告知的情况下引发上下文变化(3.2.2 On Input,A);价格或库存变化用状态消息告知,无需移动焦点(4.1.3 Status Messages,AA)。
- 输入错误以文字标明出错项并说明原因(3.3.1 Error Identification,A),例如“数量需为 6 的倍数”。
- 变体切换只请求必要数据,取消过期请求;首屏优先加载价格与按钮,媒体次之。
映射到 Shopify
核验于 2026-09-29,来自 shopify.dev 与 help.shopify.com 官方页面,只写页面所写;主题的具体行为链接固定版本正文。
| 机制 | 官方页面所写 |
|---|---|
| 商品表单 | {% form 'product', product %} 以 POST 提交到购物车添加地址 |
| 变体对象 | product.selected_variant 取地址中的 variant 参数,无则返回 nil;product.selected_or_first_available_variant 在有选中变体时返回它,不论是否可售;product.available 表示至少一个变体可售;variant.available 表示该变体是否可售 |
| 首个可售变体 | first_available_variant 的条件为库存数量大于零、库存策略为继续销售,或不跟踪库存 |
| 价格 | product.price 是最低价,compare_at_price 是最低划线价;variant.price、compare_at_price、unit_price 与 unit_price_measurement 均为币种最小单位 |
| 数量规则 | variant.quantity_rule 含 min、max、increment,默认 1、无上限、1 |
| 销售计划 | 主题需提供销售计划选择器,表单内用 name="selling_plan" 的输入保存所选计划 ID(未选则为空),变体切换时更新可选计划;requires_selling_plan 为真时不允许一次性购买;购物车与订单页也要显示计划 |
| 动态结账 | payment_button 过滤器只能用在商品表单的 form 对象上,输出加速结账容器;帮助中心写明显示哪些按钮取决于支付设置、顾客浏览器、设备与支付历史,商家不能选择品牌按钮,且只能购买单一变体;按钮为 Shadow DOM,样式用 CSS 自定义属性 |
| Ajax 加购错误 | /cart/add.js 库存不足返回 422 与说明文字;变体不存在返回 404 |
| Storefront API | ProductVariant 有 availableForSale、currentlyNotInStock(缺货但仍可购买,用于缺货预订)、quantityRule、sellingPlanAllocations、storeAvailability、compareAtPrice(高于 price 时可标记为促销) |
主题层面的数量、加购提交与加购排队见 Horizon 购买流程,商品页组合见 Horizon 商品页。商品与变体关系见商品与变体。
未核验:动态结账按钮与销售计划、缺货预订的组合行为(已读页面未写);各国划线价与参考价的法规;Storefront API 库存数量字段的访问要求。
验证一次购买区
- 默认变体商品确认无多余选项;多选项商品逐个切换,确认价格、划线价、单位价、图片和按钮同步。
- 选一个不可用组合与一个售罄变体,检查文案、按钮状态和通知入口。
- 输入最小值以下、最大值以上和非步长数量,检查提交前提示。
- 有销售计划的商品切换变体,确认计划随变体变化,加购后购物车行显示所选计划。
- 快速连续切换后立刻加购,确认加入的是最后所见的变体。
- 更换买家地区与币种;检查吸底栏、快速购买与主购买区状态一致。
- 用键盘与读屏软件走完选项到加购,检查错误提示是否被朗读。
记录变体、数量、销售计划、请求与最终购物车行,而不是只看按钮是否变成“已添加”。
固定版本主题实现
- Dawn 购买区与可售状态、Horizon 购买流程、Horizon 吸底加购与可售状态:两个主题的购买区、可售状态与吸底加购。Dawn 与 Horizon 均未在商品页内置销售计划选择器(全仓库搜索)。
- 页面级组成见 标准商品页配方 与 预售与订阅商品页配方。
固定基线为 Dawn v15.3.0 与 Horizon 4.2.0;结论限于这两个提交,均为静态源码分析,未运行验证。
待继续完善
- 动态结账按钮与销售计划、缺货预订组合行为需要在测试店铺实测。
- 缺少多市场价格、划线价与单位价一致性的样本验证。
- 未做真实读屏、移动端与弱网测试。