Shopify Checkout Extensibility 实战:别再把结账页当成一块可以随便改的主题模板
过去做 Shopify Plus,很多团队把 checkout.liquid 当成一个万能入口:插脚本、塞横幅、改 DOM、接像素、做 upsell。短期很灵活,长期却很难维护——主题一升级、支付方式一变、浏览器策略一收紧,结账链路就会出现不容易复现的问题。
Checkout Extensibility 换了一种思路:不让你修改 Shopify 托管的核心结账代码,而是在明确、安全的扩展点上放入功能。它对开发者的限制更多,但换来的是更稳定的升级路径、更清楚的隐私边界,也更容易在不同结账版本中保持一致。
先确认店铺套餐和目标市场是否具备所需的 Checkout Extensibility 能力。不同扩展点、API 和自定义能力会随 Shopify 版本与套餐变化,开发前以 Shopify 官方文档 为准。
先做迁移盘点,不要一上来就写 Extension
迁移失败最常见的原因,是把旧结账页的代码“原样翻译”成新扩展。实际上,旧代码里的事情并不都该继续存在。
先把 checkout.liquid、Additional scripts、像素、第三方 App 和主题内结账相关脚本列出来,再按下面四类处理:
| 旧功能 | 优先去向 | 说明 |
|---|---|---|
| GA4、Meta 等行为事件 | Customer Events / Web Pixel | 不应继续依赖 Thank You 页 inline script |
| 信任提示、配送说明、售后说明 | Checkout UI Extension | 放在合适的 Block 或配送扩展点 |
| 订单备注、礼品留言、定制信息 | UI Extension + Cart / Order attributes | 要验证数据最终写入位置 |
| 付款、税费、地址校验核心逻辑 | Shopify 原生能力或官方扩展点 | 不要通过 DOM 脚本绕过结账规则 |
这一步的目标不是“功能一个不丢”,而是确认每项功能是否仍然有业务价值、应该由哪个受支持的能力承接。
哪些场景适合 Checkout UI Extension
最适合放在 Checkout 的,是能帮助顾客完成当前决策、又不需要改写核心支付流程的内容。
比如配送方式下的时效说明、订单摘要附近的退换货承诺、面向特定市场的关税提示、支付方式附近的分期说明,都是合理场景。它们直接回答顾客“现在能不能下单”的问题。
反过来,如果你想做一个全屏弹窗强迫加购、拦截支付按钮、根据 DOM 猜测付款状态,说明这个需求本身就不适合放在 Checkout。把它前移到商品页或购物车,体验和稳定性通常都更好。
常见的扩展点包括:
| 扩展点 | 适合内容 |
|---|---|
purchase.checkout.block.render | 商家在 Checkout Editor 中自行放置的提示、表单、服务承诺 |
purchase.checkout.shipping-option-item.details.render | 配送方式的说明、时效或限制条件 |
purchase.checkout.payment-method-list.render-after | 支付说明、分期提示、支付安全说明 |
purchase.thank-you.block.render | 订单完成后的使用指引、会员引导、售后入口 |
不要为了“看起来专业”把内容塞满每一个位置。结账页的每一行额外信息都可能让用户犹豫,扩展的价值应该能被转化、客服咨询或退款原因验证。
一个可维护的起点:订单摘要旁的服务承诺
下面的例子使用 purchase.checkout.block.render。它不修改结账逻辑,只渲染一段可在 Checkout Editor 中移动的服务说明,适合放在订单摘要或配送信息附近。
先使用 Shopify CLI 创建官方模板:
shopify app generate extension --template checkout_ui --name checkout-service-promise然后在扩展配置中声明目标:
[[extensions.targeting]]
target = "purchase.checkout.block.render"
module = "./src/Checkout.jsx"扩展组件保持简单。不要在这里请求大量数据,更不要把它做成另一个营销落地页:
import {reactExtension, Banner, BlockStack, Text} from "@shopify/ui-extensions-react/checkout"
export default reactExtension("purchase.checkout.block.render", () => <Extension />)
function Extension() {
return (
<Banner title="安心下单">
<BlockStack spacing="tight">
<Text>订单发货后会发送物流追踪链接。</Text>
<Text>如商品不符合预期,请先联系支持团队,我们会协助处理。</Text>
</BlockStack>
</Banner>
)
}部署后,不是代码一上线就会出现。还需要在 Checkout Editor 中把应用区块添加到对应页面,并为目标市场、配送方式和设备尺寸逐一确认显示效果。
数据应该往哪里写:属性、Metafield 还是后端
Checkout 扩展经常需要收集信息,例如礼品留言、税号、配送偏好。这里先别急着做表单,先决定数据最终由谁使用。
- 仅需要随订单给客服或仓库看:优先使用订单或购物车属性。
- 需要成为长期客户资料:根据隐私合规要求,写入 Customer Metafield 或由后端系统处理。
- 需要影响价格、配送或支付可用性:先找 Shopify 提供的正式 API / Function 能力;不能用前端字段“假装改变”结账规则。
存储位置决定了权限、隐私、后台可见性和后续导出方式。它不是 UI 细节,而是业务设计。
上线前,至少走完这些路径
结账功能不能只在开发预览里点一次就发布。测试时按真实业务路径走:
- 不同国家 / Markets、不同币种、不同税费展示是否正确;
- 普通配送、加急配送和本地自提是否都能正常渲染;
- Shop Pay、信用卡、PayPal 等实际启用的支付方式是否不受影响;
- 购物车为空、优惠码、礼品卡、订阅商品、部分退款等边界情况;
- 移动端、桌面端、Safari 无痕模式与 Cookie 拒绝后的行为;
- GA4 / 广告像素事件是否仍然只触发一次,尤其是
purchase。
如果扩展涉及外部请求,还要准备接口超时或异常时的降级内容。结账页的原则很简单:你的附加功能失败时,顾客仍然必须能完成付款。
常见误区
“Checkout Extensibility 能做任何 checkout.liquid 能做的事。”
不对。它刻意限制了对 DOM 和核心流程的控制。这个限制不是缺陷,而是 Shopify 用来保证安全、兼容与可升级性的边界。
“把旧像素复制到 Thank You 页就完成迁移。”
不对。事件跟踪应迁往 Customer Events / Web Pixels,并在真实订单中检查去重和 Consent 状态。
“先把所有功能做出来,再让运营决定放哪里。”
不建议。优先做有明确问题、明确指标和明确位置的功能;UI Extension 的区块应该由 Checkout Editor 可控,而不是硬编码占满页面。
延伸阅读
- Checkout UI Extensions 官方文档 — 当前扩展点与 API 的权威参考
- Shopify Plus 高级功能 — 先确认 Plus 适用边界
- Shopify 数据追踪集成指南 — 处理 Customer Events、像素和 purchase 去重
- 购物车与结账优化 — 先解决真正导致弃单的环节