服务对象与地域限制
PuppyIP 仅面向海外合规企业及其授权人员提供服务,不面向中国大陆地区开放或提供代理服务。本服务仅限用于中国大陆境外的合法业务活动,严禁在中国大陆境内使用本服务。
代理 IP 或服务器位于境外,不改变上述限制。不得通过中转、转接、共享或转售向中国大陆境内的最终使用者提供本服务。使用前请阅读用户服务协议。
本文要点
- 行为由每个 POS UI extension 声明的 api_version 决定:2026-10 及之后的扩展会拒绝未获 POS 确认的购物车变更;2026-07 及更早版本不受这次变化影响。
- 只有 mutation 的 promise 成功完成,才能把购物车变更视为 POS 已确认;拒绝可能表示购物车未变化,也可能表示结果未知且部分变更已经发生。
- 对结果未知的写入,先读取购物车并核对实际变化,再决定下一步;不要盲目重复 bulkCartUpdate、折扣或其他批量变更。
- 为每次 await 的 mutation 添加 try/catch,并在 finally 清除应用自己的 loading 状态;本地 UI 标志不等于购物车已回滚。
- 升级前逐个检查扩展版本和 mutation 调用点,并在开发环境验证收银员切换结账、校验拒绝与未知结果的人工核对流程。
变化适用于哪个扩展
Shopify 在 2026 年 10 月 7 日公布这项 POS UI extensions 变化:行为取决于每个扩展声明的 api_version,而不是店铺统一开关。使用 2026-10 或更高版本的扩展,在 POS 没有确认购物车已改变时,相关 mutation(修改购物车的方法)会拒绝;2026-07 及更早版本保留原有行为。一个应用包含多个扩展时,应分别盘点版本。
受影响的方法包括 bulkCartUpdate、removeLineItem、applyCartDiscount、setCustomer,以及公告列出的其他折扣、客户、行项目属性和销售计划写入方法。updateLineItemQuantity 是 2026-10 新增的方法,从首次发布起就会拒绝未确认的写入。按实际调用点逐一检查;不能由这项结果契约推断每个独立的折扣计算或回写问题都已解决。
先看 promise 最终表示什么
在受影响的 API 版本中,mutation 成功完成表示 POS 已确认购物车写入。不要在确认前显示“已添加”“已应用”或继续执行依赖该结果的步骤;调用没有抛错、按钮被点击或本地计算完成,都不能代替 promise 的成功结果。
两种拒绝信息需要分开看。以“POS refused the cart update”开头的信息明确说明 POS 拒绝写入,购物车未改变;以“POS could not confirm the cart update”开头的信息表示结果未知,可能已有部分写入,要求重试前读取购物车。无效折扣、缺少客户等其他错误也会令 mutation 拒绝,不能把所有错误都归入这两类。
把未变更和结果未知分开处理
明确收到 POS refused 信息时,已知该次写入没有改变购物车。一个可能场景是收银员已经进入付款步骤,POS 暂时不再接受购物车编辑。应先确认购物车可编辑、目标操作仍符合收银员当前意图,再决定是否重新发起;不要把拒绝当作可无限自动重试的信号。
收到 could not confirm 信息时,不要立即重放原请求。先读取当前购物车,把已观察到的状态与想要完成的变化逐项比较,再决定缺少什么。尤其不要在状态不明时直接重送会替换整份购物车的 bulkCartUpdate,或再次应用折扣;购物车可能已完成全部或部分目标变化。
用 try/catch 处理错误,并在 finally 清除加载状态
每个由 await 调用的购物车 mutation 都应在调用点进入 try/catch。只有 promise 成功完成后,才把本地界面标记为已确认;在 catch 中记录错误并按可识别的拒绝信息区分“未改变”和“结果未知”,对其他校验或系统错误也保留可见的失败处理。
无论成功还是拒绝,都在 finally 中清除应用自己的 loading 标志,避免异步失败让按钮或旋转提示一直卡住。清除提示、重置应用内的折扣徽标,或恢复本地暂存状态,都不会撤销 POS 中已经发生的购物车写入;结果未知时应明确显示待核对,而不是把 UI 重置说成购物车回滚。
读取购物车帮助核对,但不要扩大其保证
Cart API 的 shopify.cart.current.value 提供当前购物车的读取入口,购物车的 editable 属性可用于了解 POS 是否允许编辑,current.subscribe() 可观察购物车状态变化。这些接口用于读取和观察,不会替代 mutation 自身的结果处理;editable 未定义时,官方文档要求为兼容性按可编辑处理。
拒绝后读取到的购物车状态可以帮助你与预期变化核对,但文档没有承诺一次立即读取就能确定最终服务器结果。若结果仍不清楚,保持未确认状态并交由收银员按购物车实际内容人工核对;在确认缺少的变化之前,不要再次提交同一批写入。
升级前做调用点和收银流程检查
升级到 2026-10 前,检查每个扩展的 api_version,并验证每个购物车 mutation 的拒绝路径。暂时不能处理拒绝时,可在官方支持窗口内继续使用 2026-07 或更早版本;这不是永久保留旧版的承诺。当前版本页面将 2026-07 列为稳定版本,具体支持与退役安排仍应核对官方版本规则,本文不另造截止日期。
建议在开发扩展和测试收银流程中检查收银员转入付款后写入被拒、校验错误,以及结果未知时先读取并人工核对等路径。这些是建议执行的验证项,不代表本文已经运行了测试、修改了商店或证明任何生产设备的行为。
资料来源
常见问题
必须把所有调用改成 async/await 吗?
不必。公告也允许在 promise 上添加 .catch() 处理拒绝。无论使用哪种写法,都要让成功、错误和清理逻辑连接到实际返回的 promise,避免调用已经结束,界面仍按默认成功继续。
连续执行几个购物车修改,后一个失败会自动撤销前面的吗?
不要作此假设。公告没有为应用自行串联的多个调用提供整组事务或自动回滚保证。记录每一步结果,后续失败后核对实际购物车,再决定剩余操作。
换一个代理出口能解决这两种 POS 拒绝吗?
代理出口不会改变购物车是否可编辑、扩展 API 版本或 POS 的写入结果。先按实际拒绝信息处理业务状态;只有另有 DNS、TLS 或连接失败证据时,才单独排查网络路径。