WooCommerce 文档
相关英文(Store/Blocks):WooCommerce Developer Docs (https://docs.cocobook.com/books/woocommerce-developer-docs)
WooCommerce 官方文档中文稿,覆盖入门、功能、主题与扩展开发要点。
- 购物车令牌
- Store API 设计原则
- 随机数 (Nonce)
- Store API 接口的限流
- 购物车令牌
- Store API 接口的速率限制
- 可扩展的 API 接口
- 添加字段并传递值
- 暴露你的数据
- 可用的格式化器
- 动态更新购物车
- 购物车优惠券 API
- 购物车项目 API
- 购物车 API
- 结账订单 API
- 结账 API
- 订单 API
- 产品 属性 术语 API
- 产品属性 API
- 产品品牌 API
- 产品类别 API
- 产品集合数据 API
- 产品评论 API
- 产品标签 API
- 产品 API
- 购物车 API
- 结账订单 API
- 订单 API
- 产品 属性 术语 API
- 产品品牌 API
- 产品分类 API
- 产品评论 API
- 购物车令牌
- WooCommerce 编码规范
- CSS/Sass 命名规范
- WooCommerce 语法、标点符号和首字母大写指南
- 命名规范
- 如何为简单产品和可变产品添加自定义字段
- 使用 WooCommerce CRUD 对象进行开发
- 数据存储基础
- 如何管理 WooCommerce 数据存储
- WooCommerce 日志记录
- 0043-best-practices-data-management-docs-data-storage
- 使用 WooCommerce CRUD 对象进行开发
- 更新国家和行政区划
- 如何翻译 WooCommerce
- 更新国家和行政区划
- 如何配置 WooCommerce 的缓存插件
- WooCommerce 扩展的性能最佳实践
- 如何优化 WooCommerce 商店的性能
- 如何请求 WooCommerce 插件评论
- 各种建议和指导
- 向用户通报错误修复和功能请求
- 如何应对 WooCommerce 插件的负面评价
- 利用 WooCommerce 扩展的特性请求功能
- 如何利用您的支持团队来响应反馈
- 何时请求 WooCommerce 扩展的评论
- 各种建议和指导
- 向用户通报错误修复和功能请求
- 如何回应 WooCommerce 扩展的负面评价
- 如何利用您的支持团队来响应反馈
- 何时请求 WooCommerce 扩展的评论
- 如何防止 WooCommerce 网站的数据泄露
- WooCommerce 安全最佳实践
- 如何防止 WooCommerce 网站的数据泄露
- 可分享的结账链接
- 自定义 WooCommerce 端点 URL
- 理解在 WooCommerce 中移除 URL 基础部分的风险
- 在 WooCommerce 中使用 Webhook
- 理解 WooCommerce 端点
- 理解在 WooCommerce 中移除 URL 基础部分的风险
- 附加结账字段
- 可用的插槽
- 结账工具
- DOM 事件
- 结账模块如何处理订单
- 移除结账字段
- 结账流程和事件
- 在结账块中过滤付款方式
- 付款方式集成
- 付款方式集成
- 内部区块类型
- 购物车明细项
- 结账和下单按钮
- 优惠券
- 订单摘要项目
- Totals footer item
- 产品集合块发出的 DOM 事件
- 在产品集合块中注册自定义集合
- 块中的可扩展性
- 常见问题
- Blocks 参考
- 处理脚本、样式和数据
- 客户端和服务器之间的数据流概述
- Slot 和 Fill
- 购物车商店 (`wc/store/cart`)
- 结账商店 (`wc/store/checkout`)
- Collections Store (`wc/store/collections`)
- 支付存储 (`wc/store/payment`)
- 查询状态商店 (`wc/store/query-state`)
- 结构化数据存储 (`wc/store/schema`)
- Store Notices Store (`wc/store/store-notices`)
- 验证数据存储 (`wc/store/validation`)
- 商店通知商店 (`wc/store/store-notices`)
- 短代码的钩子替代方案
- 迁移的旧版钩子
- Hook alternatives
- Migrated legacy hooks
- 如何向 WooCommerce 结账阻止添加额外的字段
- 如何让您的 WooCommerce 附加结账字段在结账页面上根据条件显示
- 与结账模块集成保护功能
- 添加一个国家
- 添加货币和符号
- 添加或修改州/省
- 调整数量输入框的值
- 在登录/注册表单上方添加一条信息
- 更改货币符号
- 检查付款方式是否支持退款、订阅或预购
- 配置特殊税收场景的代码示例
- 使用操作和过滤器自定义结账字段
- 以编程方式禁用市场场所建议功能
- 在您的主题或网站中显示自定义字段
- 免费配送自定义设置
- 适用于旧版本地自提的高级设置和自定义
- 向已记录的数据添加链接
- 确保您的翻译升级安全
- 修改显示的相关产品数量
- 覆盖循环模板,并在“加入购物车”按钮旁边显示数量
- 重命名一个国家
- SSL 和 HTTPS 和 WooCommerce
- 移除和禁用 WooCommerce 邮件
- 卸载并移除所有 WooCommerce 数据
- 有用的核心函数
- 使用 NGINX 服务器保护您的上传目录
- 0135-code-snippets-docs-add-or-modify-states
- 检查付款方式是否支持退款、订阅或预购
- 以编程方式禁用市场场所建议功能
- 重命名一个国家
- CSS SASS 编码规范和命名约定
- WooCommerce 核心 API 中的关键流程
- 常见问题
- 如何评估 Pull Request 的影响
- 核心功能的弃用
- 处理 WooCommerce 中的 SCSS 和 JS 压缩
- 命名规范
- 报告安全问题
- 字符串本地化指南
- WooCommerce Git Flow
- WooCommerce Core API 中的关键流程
- 处理 WooCommerce 中的 SCSS 和 JS 压缩
- 报告安全问题
- 字符串本地化指南
- WooCommerce Git Flow
- 贡献技术文档
- 技术文档风格指南
- 贡献技术文档
- WooCommerce 的代码回溯
- 构建和发布版本
- WooCommerce 发布监控
- JavaScript 包的发布
- WooCommerce 的小版本发布请求
- 补丁版本
- WooCommerce 预发布版本
- WooCommerce 发布计划
- 发布故障排除与恢复
- 发布流程
- JavaScript 包的发布
- Beta 测试
- WooCommerce 核心关键流程
- 撰写高质量的测试说明
- WooCommerce 核心关键流程
- 可访问性最佳实践
- WooCommerce 扩展的兼容性和互操作性
- WooCommerce 扩展开发最佳实践
- WooCommerce 扩展的 GDPR 合规性指南
- WooCommerce 扩展的隐私标准
- WooCommerce 扩展的支持和文档
- WooCommerce 扩展开发最佳实践
- 如何添加操作和过滤器
- `changelog.txt` 格式
- 如何检查 WooCommerce 是否已激活
- WooCommerce 中的类
- WooCommerce 扩展的 WordPress 插件头部评论示例
- 管理插件停用和卸载
- 维护和更新 WooCommerce 扩展
- `wc_get_orders()` 和订单查询
- `wc_get_products` 和产品查询
- WooCommerce 插件 API 回调
- 管理插件停用和卸载
- 如何将自定义产品类型添加到“添加产品”向导列表
- 如何创建自定义产品导览
- 如何实现商家入职流程
- 集成即将推出的模式
- 如何构建你的第一个扩展
- 如何设计一个简单的扩展
- 如何向设置选项卡添加一个部分
- WooCommerce 邮件编辑器集成指南
- 如何添加商店管理链接
- 为 WooCommerce 扩展创建自定义设置
- 设置 API
- 管理 WooCommerce 菜单和分类法归档中的自定义属性
- 将管理页面集成到 WooCommerce 扩展中
- 可访问性
- 最佳实践
- 颜色
- 导航
- 通知
- 入门指南
- 设置
- 任务列表和收件箱
- 测试
- 可访问性
- 颜色
- 设置
- 测试
- 地址自动补全提供者实现
- 如何向分析报告和 CSV 下载添加列
- 如何扩展 WooCommerce 分析报告
- 邮件编辑器日志记录
- Email HTML - 最佳实践
- 电子邮件预览集成
- 邮件编辑器日志记录
- HPOS 命令行工具
- 如何启用高性能订单存储
- 大型商店启用 WooCommerce HPOS 的指南
- HPOS 扩展使用指南
- HPOS 订单查询 API
- WooCommerce 支付网关 API
- WooCommerce 支付网关插件基础
- WooCommerce 支付令牌 API
- 配送方法 API
- AI
- 调试资源
- 开发者工具
- 设置您的开发环境
- 项目结构
- 模板和示例商店数据
- 低代码开发工具
- 版本控制和部署
- 购物车和结账模块的主题定制
- CSS 样式设置用于主题
- Woo blocks 主题定制
- 主题的 CSS 样式
- 经典主题开发手册
- WooCommerce 中的条件标签
- 如何修复过时的 WooCommerce 模板
- 主题开发者须知:图片尺寸
- 如何设置和使用子主题
- 模板结构 & 通过主题覆盖模板
- 主题设计和用户体验指南
- 缩略图重新生成
- 如何修复过时的 WooCommerce 模板
- 支付按钮布局
- 支付按钮的大小和结构
- 支付按钮样式
- 支付集成与设置
- 可访问性
- 品牌标识
- 自定义
- 演示和示例内容
- 品牌形象
- 可访问性
- 品牌标识
- 自定义
- 演示和示例内容
- WooCommerce CLI 常见问题
- WooCommerce CLI 概述
- 如何使用 WooCommerce CLI
- WooCommerce CLI 命令
- WooCommerce CLI 示例
- WooCommerce CLI 示例
- Marketplace 内容样式指南
- 快速入门
- 在 Woo Marketplace 中管理产品
- Marketplace 插件的盈利预期
- 产品更新指南和最佳实践
- Woo Marketplace 的支持指南
购物车令牌
获取购物车令牌
对 /cart 接口的请求会返回一个 Cart-Token 头部,该头部包含一个令牌,该令牌可以在后续的请求中作为头部发送到 API 商店的购物车和结账接口,以标识购物车。
获取购物车令牌最快的方法是发送一个 GET 请求到 /wp-json/wc/store/v1/cart,并观察响应头部。 您应该在该头部中看到一个 Cart-Token。
如何使用 Cart-Token
要使用 Cart-Token,请将其包含在请求的头部中。 响应将包含与 Cart-Token 关联的会话的当前购物车状态。
示例:
curl --header "Cart-Token: 12345" --request GET https://example-store.com/wp-json/wc/store/v1/cart
使用相同的方法,您可以使用 Cart-Token 在 /checkout 路由上进行结账。
Store API 设计原则
在扩展、创建或更新 Store API 的接口时,应考虑以下原则。
接口必须包含一个 明确定义的 JSON 结构化数据
每个接口/端点都需要特定的输入数据结构,并且应使用定义的、可预测的结构返回数据。 这在 JSON 结构化数据中定义,其中包含 API 可以返回的所有属性的完整列表,以及它可以接受的输入参数。
明确定义的结构化数据还提供了一层安全性,因为它使我们能够验证和清理发送到 API 的请求。
在定义结构化数据时,请参考 WordPress REST API 手册,其中记录了可用的属性和类型,以及 JSON 结构化数据标准。 此外:
- 属性应使用 snake_case 🐍 格式。
- 应避免使用含糊的术语,并且属性名称应尽量使用易于理解的语言,而不是 "WooCommerce" 术语或设置名称。
- 属性应使用美式英语定义,但字段的描述应进行本地化。
- 允许使用多种类型,例如,如果某个值不适用,可以使用
null类型。 - 在可能的情况下,建议使用
sanitize_callback和validate_callback,以确保在处理请求之前,数据以正确的格式接收。
如果您在定义一致的结构化数据时遇到困难,则您的方法可能存在问题。 一个常见的实际例子是表示 文章标签。 可能会有人想在响应中使用别名 (Slug) 作为属性字段名:
tags: [
"my-tag": {
// ...标签数据
},
"my-other-tag": {
// ...标签数据
}
]
但是,这在结构化数据中难以表示,并且对客户端来说不可预测。 更好的方法是使用一个数据数组,其中一个属性是别名:
tags: [
{
"slug": "my-tag",
// ...标签数据
},
{
"slug": "my-other-tag",
// ...标签数据
}
]
接口应围绕具有单个类型结构化数据的资源进行设计
接口应围绕资源(名词)而不是操作(动词)进行设计。 接口还应仅返回由其结构化数据定义的单一类型的数据。 例如:
| 接口 | 资源类型 | 预期数据 |
|---|---|---|
wc/store/v1/cart |
购物车 | 一个购物车对象 |
wc/store/v1/cart/items |
购物车商品 | 购物车商品对象的列表 |
wc/store/v1/products |
产品 | 产品对象的列表 |
wc/store/v1/products/1 |
产品 | 一个产品对象 |
在 Store API 中,有两个值得注意的例外情况,即 错误 和 购物车操作。
错误处理
错误,包括验证错误,应该返回一个错误响应码(4xx 或 5xx)和一个 WP_Error 对象。AbstractRoute 类将负责将 WP_Error 对象转换为有效的 JSON 响应。
错误消息应该进行本地化,但不需要使用面向客户的语言(客户端应该使用给定的错误码来创建必要的面向客户的提示)。
错误码应该以 woocommerce_rest_ 为前缀。
购物车操作
某些端点设计用于避免客户端需要进行多次 API 调用。这纯粹是为了方便。
例如,wc/store/v1/cart/add-item 端点接受一个数量和一个产品 ID,但返回完整的购物车对象,而不是仅仅更新的项目列表。
暴露的数据必须属于当前用户或为非敏感数据
资源,包括客户和订单数据,应该仅反映当前会话。不要返回其他客户的数据,因为这会违反隐私和安全。
允许在响应中包含商店数据,例如商店货币的 设置,但应避免 私有或敏感数据。为了允许更广泛地访问数据,您必须使用经过身份验证的 WC REST API。
从 API 返回的数据不应该进行 转义(这由客户端负责进行渲染),但应该进行清理。例如,HTML 应该通过 wp_kses_post 进行处理。
客户端有责任正确地转义来自 API 的数据,但我们应该尽量避免返回可能不安全的数据。
资源集合应该进行分页
大量的数据应该进行分页,以避免对 服务器 造成过载。例如,返回产品集合。
- 使用响应头
X-WP-Total、X-WP-TotalPages和 Link 来指示 可用 的资源。 - 使用参数
page和per_page来检索特定的页面。 per_page的最大允许值为 100。
API 回复应使用标准的 HTTP 状态码
在返回内容时,应使用有效的 HTTP 回复码,例如:
200 OK用于成功的回复(这是默认的回复码)。201 Created用于创建资源,例如,添加新的购物车商品或应用新的优惠券。204 No Content用于成功的删除操作。400 Bad Request当缺少必需的参数时。403 Forbidden当请求不允许时,例如,如果提供的安全随机数无效。404 Not Found如果资源不存在。409 Conflict如果资源无法更新,例如,如果购物车中的某个内容无效并被删除。
关于 DELETE 请求的说明:在 WordPress REST API 中,一种常见的模式是返回已删除的对象。在 Store API 的情况下,我们选择返回一个空回复,并使用状态码 204 No Content,这更有效。
应该尽可能避免破坏性变更
Store API 通过使用结构化数据与 API 消费者建立契约。除非绝对必要,否则不应破坏此契约。如果必须进行破坏性变更,则需要发布 Store API 的新版本。
破坏性变更是指任何更改现有结构化数据格式、删除结构化数据属性、删除现有路由或对任何已公开且可能已被消费者使用的内容进行向后不兼容的更改。可以通过弃用现有属性而不是删除它们,或者弃用路由并将它们替换为不同的路由来避免破坏性变更,如果需要进行重大更改。
非破坏性变更始终允许,而无需增加 API 版本。以下是一些示例:
- 向结构化数据添加新的属性。
- 添加新的路由、端点、方法。
- 添加可选的请求参数。
- 重新排序回复字段。
只有当错误修复导致向后不兼容的更改时,版本才会增加。除非存在需要回溯修复的安全问题,否则不会将修复回滚到过去的 API 版本。
随机数 (Nonce)
随机数是用于验证请求来源和意图的数字,以实现安全目的。 您可以阅读更多关于 WordPress 代码库中的随机数 的信息。
需要使用随机数的 API 接口
对 /cart 接口的 POST 请求以及对所有 /checkout 接口的请求都需要使用随机数才能正常工作。 如果未提供有效的随机数,将返回错误响应,除非您正在使用 购物车令牌 代替。
通过请求发送随机数
随机数包含在请求头中。 创建一个名为 Nonce 的请求头。 API 将会验证此头。
示例:
curl --header "Nonce: 12345" --request GET https://example-store.com/wp-json/wc/store/v1/checkout
在成功发送请求后,将发送一个更新后的 Nonce 头,客户端需要将其存储并更新,以便进行后续请求。
从 WordPress 生成安全随机数
必须使用 wp_create_nonce 函数,并使用键 wc_store_api 来创建随机数。
wp_create_nonce( 'wc_store_api' )
没有其他机制可以用于创建随机数。
开发阶段禁用随机数验证
如果您想在不提供随机数的情况下测试 REST 接口,可以使用以下过滤器:
add_filter( 'woocommerce_store_api_disable_nonce_check', '__return_true' );
如果 woocommerce_store_api_disable_nonce_check 的值为 true,则会绕过随机数验证。
注意:这只应在不重要的安全性的开发环境中进行。 请勿在生产环境启用此功能。
Store API 接口的限流
限流 功能现已适用于 Store API 接口。这是一个可选功能,默认情况下是禁用的。可以通过遵循 以下说明 来启用它。
其主要目的是防止对接口的滥用,以及避免因过多的调用而导致运行 Store 的服务器性能下降。
限流跟踪由以下方式控制:用户 ID(已登录用户)、IP 地址(未认证的请求),或者通过过滤器定义的逻辑来识别和分组请求。
它还提供标准的支持,可以在代理、负载均衡器等环境中使用。这也是一个可选功能,默认情况下是禁用的。
UI 控制
目前,此功能只能通过 woocommerce_store_api_rate_limit_options 过滤器进行控制。要通过 UI 进行控制,可以使用以下社区插件:WooCommerce 限流 UI 插件。
结账限流
您可以通过以下步骤,在 WooCommerce -> 设置 -> 高级 -> 功能 中启用“限流结账模块和 Store API”,从而为结账页面提交订单和 POST /checkout 接口启用限流。
通过 UI 启用后,限流仅适用于 POST /checkout 接口以及结账模块的提交订单流程。限制为每 60 秒最多 3 个请求。
限制信息
默认情况下,可以在 10 秒的时间范围内最多发出 25 个请求。这些限制可以通过 选项过滤器 进行修改。
受限流影响的方法
仅 POST 请求受到限流的影响。使用 X-HTTP-Method-Override 头部(例如,通过 wp.apiFetch 发送的 PUT、PATCH 请求)的请求不受到限流的影响。
限流选项过滤器
提供一个过滤器,用于设置限流选项:
add_filter( 'woocommerce_store_api_rate_limit_options', function() {
return [
'enabled' => false, // 启用/禁用限流。默认:false
'proxy_support' => false, // 启用/禁用代理支持。默认:false
'limit' => 25, // 每段时间内的请求限制。默认:25
'seconds' => 10, // 时间范围(秒)。默认:10
];
} );
代理标准支持
如果 Store 运行在代理、负载均衡器、缓存服务、CDN 等环境,则支持通过标准 IP 转发头部来按 IP 地址进行限流,这些头部包括:
X_REAL_IP|CLIENT_IP:常用的自定义实现,用于简化获取请求的原始 IP 地址X_FORWARDED_FOR:用于识别原始 IP 地址的事实标准头部,文档X_FORWARDED:文档,RFC 7239
此功能默认情况下是禁用的。
通过自定义请求指纹启用速率限制
对于更高级的用例,您可以启用基于自定义指纹的速率限制。 这允许自定义实现来分组请求,而无需依赖已登录的用户 ID 或 IP 地址。
自定义基本示例,用于按 User-Agent 和 Accept-Language 组合分组请求
add_filter( 'woocommerce_store_api_rate_limit_id', function() {
$accept_language = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) : '';
return md5( wc_get_user_agent() . $accept_language );
} );
限制使用信息的可观察性
当前限制信息可以通过自定义响应头进行观察:
RateLimit-Limit每段时间允许的最大请求数.RateLimit-Remaining当前时间内剩余的请求数.RateLimit-Reset下一个时间段重置的 Unix 时间戳.RateLimit-Retry-After直到请求可以再次被接受的秒数。仅在达到限制时显示.
响应头示例
RateLimit-Limit: 5
RateLimit-Remaining: 0
RateLimit-Reset: 1654880642
RateLimit-Retry-After: 28
跟踪限制滥用
这使用了一个修改后的 wc_rate_limit 表,其中添加了一个额外的 remaining 列,用于跟踪在任何给定的请求窗口内的请求计数。
为了便于扩展,实现了一个自定义动作 woocommerce_store_api_rate_limit_exceeded,用于跟踪此类滥用行为。
自定义跟踪使用示例
add_action(
'woocommerce_store_api_rate_limit_exceeded',
function ( $offending_ip, $action_id ) { /* 自定义跟踪实现 */ }
);
购物车令牌
获取购物车令牌
对 /cart 接口的请求会返回一个 Cart-Token 头部,该头部包含一个令牌,该令牌随后可以作为请求头部发送到 API 商店的购物车和结账接口,以标识购物车。
获取购物车令牌最快的方法是发送一个 GET 请求到 /wp-json/wc/store/v1/cart,并观察响应头部。 您应该在该头部中看到一个 Cart-Token。
如何使用 Cart-Token
要使用 Cart-Token,请将其包含在请求的头部中。 响应将包含与 Cart-Token 关联的会话中的当前购物车状态。
示例:
curl --header "Cart-Token: 12345" --request GET https://example-store.com/wp-json/wc/store/v1/cart
使用相同的方法,您可以使用 Cart-Token 在 /checkout 路由上进行结账。
Store API 接口的速率限制
速率限制 适用于 Store API 接口。这是一个可选功能,默认情况下是禁用的。可以通过以下说明启用它。
其主要目的是防止对接口的滥用,以及避免因过多的调用而导致运行 Store 的服务器性能下降。
速率限制的跟踪由以下方式控制:用户 ID(已登录用户)、IP 地址(未认证的请求),或者通过过滤器定义的逻辑来识别和分组请求。
它还提供标准的支持,可以在代理服务器、负载均衡器等环境中运行。这也是一个可选功能,默认情况下是禁用的。
UI 控制
目前,此功能仅通过 woocommerce_store_api_rate_limit_options 过滤器进行控制。要通过 UI 进行控制,可以使用以下社区插件:Rate Limiting UI for WooCommerce。
结账速率限制
您可以启用结账“提交订单”操作和 POST /checkout 接口的速率限制,方法是通过 UI 转到 WooCommerce -> 设置 -> 高级 -> 功能,并启用“Rate limiting Checkout block and Store API”。
通过 UI 启用后,速率限制仅适用于 POST /checkout 接口和结账模块的“提交订单”流程。限制为每 60 秒最多 3 个请求。
限制信息
默认情况下,可以在 10 秒的时间范围内最多发出 25 个请求。这些可以通过选项过滤器进行更改。
受速率限制影响的方法
仅对 POST 请求进行速率限制。使用 X-HTTP-Method-Override 头部(例如,通过 wp.apiFetch 发送的 PUT、PATCH 请求)的请求不受到速率限制。
速率限制选项过滤器
提供一个过滤器,用于设置速率限制的选项:
add_filter( 'woocommerce_store_api_rate_limit_options', function() {
return [
'enabled' => false, // 启用/禁用速率限制。默认:false
'proxy_support' => false, // 启用/禁用代理支持。默认:false
'limit' => 25, // 每段时间内的请求限制。默认:25
'seconds' => 10, // 时间范围(秒)。默认:10
];
} );
代理标准支持
如果 Store 运行在代理服务器、负载均衡器、缓存服务、CDN 等之后,通过标准的 IP 转发头来限制基于 IP 的访问是支持的,这些头包括:
X_REAL_IP|CLIENT_IP自定义的常用实现,用于简化获取请求的源 IP 地址X_FORWARDED_FOR用于标识源 IP 地址的事实标准头,文档X_FORWARDED文档, RFC 7239
默认情况下,此功能是禁用的。
启用基于请求自定义指纹的速率限制
对于更高级的用例,您可以启用基于自定义指纹的速率限制。 这允许自定义实现来分组请求,而无需依赖已登录的用户 ID 或 IP 地址。
自定义基本示例,用于通过 User-Agent 和 Accept-Language 组合来分组请求
add_filter( 'woocommerce_store_api_rate_limit_id', function() {
$accept_language = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) : '';
return md5( wc_get_user_agent() . $accept_language );
} );
限制使用信息的可观察性
当前限制信息可以通过自定义响应头进行观察:
RateLimit-Limit每个时间段的最大请求数。RateLimit-Remaining当前时间段内可用的请求数。RateLimit-Reset下一个时间段重置的 Unix 时间戳。RateLimit-Retry-After直到请求可以再次被允许的时间,以秒为单位。仅在达到限制时显示。
响应头示例
RateLimit-Limit: 5
RateLimit-Remaining: 0
RateLimit-Reset: 1654880642
RateLimit-Retry-After: 28
跟踪限制滥用
此功能使用修改后的 wc_rate_limit 表,其中包含一个额外的 remaining 列,用于跟踪在任何给定的请求窗口内的请求计数。
已实现一个自定义动作 woocommerce_store_api_rate_limit_exceeded,以实现可扩展性,用于跟踪此类滥用行为。
自定义跟踪使用示例
add_action(
'woocommerce_store_api_rate_limit_exceeded',
function ( $offending_ip, $action_id ) { /* 自定义跟踪实现 */ }
);
可扩展的 API 接口
Store API 的某些接口可以通过名为 ExtendSchema 的类进行扩展。 这允许您自定义 Store API 返回的数据(包括结构化数据),以便您的应用程序或插件可以消费这些数据。
有关扩展 Store API 的更多信息,您可能还对以下内容感兴趣:
以下是可以使用 ExtendSchema 进行扩展的可用接口列表,以及一些示例用例。
产品
主要的 wc/store/products 接口可以通过 ExtendSchema 进行扩展。 数据通过每个 product 在响应数组中的 extensions 键提供。
可以使用 ProductSchema::IDENTIFIER 键来扩展此接口。 对于此接口,您的 data_callback 回调函数会传递 $product 作为参数。 您的 schema_callback 函数不传递任何其他参数;所有产品应共享相同的结构化数据。
用例
此接口适用于添加有关单个产品的附加数据。 这可能是一些元数据、额外的定价,或任何其他支持产品页面上自定义组件的数据。
示例
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => ProductSchema::IDENTIFIER,
'namespace' => 'my_plugin_namespace',
'data_callback' => function( $product ) {
return array(
'my_meta_data' => get_post_meta( $product->get_id(), 'my_meta_data', true ),
);
},
'schema_callback' => function() {
return array(
'properties' => array(
'my_meta_data' => array(
'type' => 'string',
),
),
);
},
'schema_type' => ARRAY_A,
)
);
购物车
主要的 wc/store/cart 接口可以通过 ExtendSchema 进行扩展。 数据通过响应中的 extensions 键提供。
可以使用 CartSchema::IDENTIFIER 键来扩展此接口。 对于此接口,您的 data_callback 和 schema_callback 函数不传递任何其他参数。
用例
此接口适用于向购物车页面添加附加数据,例如,有关购物车中商品的额外数据,或支持购物车页面上显示的自定义组件所需的一切。
示例
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => CartSchema::IDENTIFIER,
'namespace' => 'my_plugin_namespace',
'data_callback' => function() {
return array(
'foo' => 'bar',
);
},
'schema_callback' => function() {
return array(
'properties' => array(
'foo' => array(
'type' => 'string',
),
),
);
},
'schema_type' => ARRAY_A,
)
);
购物车商品
wc/store/cart/items 接口,该接口也可用作 wc/store/cart 内部的 items 键。 数据将包含在 items 数组的每个商品中。
该接口可以通过 CartItemSchema::IDENTIFIER 键进行扩展。 对于此接口,您的 data_callback 回调函数将接收 $cart_item 作为参数。 您的 schema_callback 函数不接收任何其他参数;所有购物车商品应使用相同的结构化数据。
用途
此接口适用于添加有关单个购物车商品的附加数据。 这可能是一些元数据、附加价格,或任何其他支持购物车页面上自定义组件或扩展的功能。
示例
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => CartItemSchema::IDENTIFIER,
'namespace' => 'my_plugin_namespace',
'data_callback' => function( $cart_item ) {
$product = $cart_item['data'];
return array(
'my_meta_data' => get_post_meta( $product->get_id(), 'my_meta_data', true ),
);
},
'schema_callback' => function() {
return array(
'properties' => array(
'my_meta_data' => array(
'type' => 'string',
),
),
);
},
'schema_type' => ARRAY_A,
)
);
结账
wc/store/checkout 接口可以通过 ExtendSchema 进行扩展。 响应中的 extensions 键包含可用的附加数据。
该接口可以通过 CheckoutSchema::IDENTIFIER 键进行扩展。 对于此接口,您的 data_callback 和 schema_callback 函数不接收任何其他参数。
用途
此接口适用于向结账页面添加附加数据,例如自定义支付方法,该方法需要从用户或服务器收集额外的数据。
⚠ 重要:不要在此接口中泄露任何敏感数据,因为它对公众开放。 这包括用于支付服务的私钥。
示例
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => CheckoutSchema::IDENTIFIER,
'namespace' => 'my_plugin_namespace',
'data_callback' => function() {
return array(
'foo' => 'bar',
);
},
'schema_callback' => function() {
return array(
'properties' => array(
'foo' => array(
'type' => 'string',
),
),
);
},
'schema_type' => ARRAY_A,
)
);
添加字段并传递值
本文档描述了开发者如何将一个输入字段插入到结账块中,并将该字段的值传递给 Store API,以便在处理结账时可用。
概述
开发者可以通过添加新的内部块并处理额外的数据,来扩展结账块,从而通过结账 POST 请求进行处理。 这涉及到利用古腾堡和 WooCommerce Blocks 提供的可扩展性接口。 我们的教程中对这一点进行了更详细的说明:教程:扩展 WooCommerce 结账块以添加自定义配送选项。
前置条件
- 了解 React 和古腾堡块编辑器。
- 熟悉 WooCommerce Blocks 的可扩展性接口和 Store API。
逐步指南
1. 设置您的开发环境
确保您的项目中包含以下文件:
index.js: Webpack 的入口点,用于导入和注册块类型。edit.js: 处理在编辑器界面中渲染块。block.json: 提供块的元数据和配置。block.js: 管理块的状态和用户交互。frontend.js: 注册结账块组件以在前端使用。
请参考此教程,了解向结账块添加自定义配送选项的示例。
2. 将新的字段块添加到结账块中
要将字段块添加到结账块中,您需要在块的 block.json 文件中添加以下条目:
"parent": [ "woocommerce/checkout-shipping-methods-block" ],
"attributes": {
"lock": {
"type": "object",
"default": {
"remove": true,
"move": true
}
}
}
- lock 属性 是一个对象,用于控制是否可以删除或移动该块。 默认情况下,lock 属性设置为允许删除和移动块。 但是,通过修改 lock 属性,您可以“强制”块不可删除。 例如,您可以将 remove 和 move 属性都设置为 false,以防止删除或移动该块。
- parent 属性 指定此块应嵌套在哪个父块中。 它确定块将在哪里渲染。 在我们的示例中,该块是
woocommerce/checkout-shipping-methods-block的子块。 这意味着您的块将在woocommerce/checkout-shipping-methods-block中渲染。 如果不需要配送方法块,则您的块将不会渲染。
3. 设置自定义结账数据
我们可以将添加的字段数据设置为 setExtensionData 函数,以便在处理订单时将其发送到 wc/store/checkout 端点:
setExtensionData(
'namespace-of-your-block',
'key-of-your-data',
value
);
参数
- namespace
string- 您的块的命名空间。 - key
string- 您的数据的键。 - value
any- 您的数据的价值。
工作原理
setExtensionData通过 props 传递给内部块。- 它更新
wc/store/checkout数据存储中的extensionData键。 - 当向结账端点发送 POST 请求时,此键作为请求体的一部分传递。
代码示例
// block.js
export const Block = ( { checkoutExtensionData, extensions } ) => {
/**
* `setExtensionData` 会使用提供的值更新 `wc/store/checkout` 数据存储。
* 它可以用于在提交结账表单时,将客户端数据传递到服务器。
*/
const { setExtensionData } = checkoutExtensionData;
}
// ... 一些代码
useEffect( () => {
/**
* 此代码应使用 `setExtensionData` 来更新结账数据存储中 `namespace-of-your-block` 命名空间下的 `key-of-your-data` 键。
*/
setExtensionData(
'namespace-of-your-block',
'key-of-your-data',
value
);
}, [ setExtensionData, value ] );
截图
Redux Dev tool 的截图,显示在调用 setExtensionData 之前和之后的的数据存储:
| 之前 | 之后 |
|---|---|
4. 处理结账 POST 请求
为了处理添加的字段数据,我们需要扩展 Store API,以便告知它期望接收额外的数据。更多详情请参阅 在 Store API 中暴露您的数据。
代码示例
我们将使用以下 PHP 文件作为示例:
custom-inner-block-blocks-integration.php文件:当使用结账 blocks 时,在前端注册脚本、样式和数据。 更多详情请参考 IntegrationInterface 文档。
use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;
/**
* 用于与 WooCommerce Blocks 集成的类
*/
class Custom_Inner_Block_Blocks_Integration implements IntegrationInterface {
/**
* 集成的名称。
*
* @return string
*/
public function get_name() {
return 'new-field-block';
}
/**
* 调用时,会执行任何与集成相关的初始化/设置。
*/
public function initialize() {
// ... 这里有一些代码:(例如,初始化函数,用于注册脚本和样式,以及其他指令)
}
// ... 其他函数
}
custom-inner-block-extend-store-endpoint.php文件:扩展 Store API,并添加钩子以保存和显示您的新字段块的说明。 默认情况下,此功能不会将自定义块中的数据保存到任何地方,但您可以添加自己的逻辑将数据保存到数据库。
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;
/**
* 您的新字段块扩展 Store API。
*/
class Custom_Inner_Block_Extend_Store_Endpoint {
/**
* 存储 Rest 扩展实例。
*
* @var ExtendRestApi
*/
private static $extend;
/**
* 插件标识符,每个插件独一无二。
*
* @var string
*/
const IDENTIFIER = 'new-field-block';
/**
* 启动类和所需的钩子。
*
*/
public static function init() {
self::$extend = Automattic\WooCommerce\StoreApi\StoreApi::container()->get( Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema::class );
self::extend_store();
}
/**
* 将实际数据注册到每个端点。
*/
public static function extend_store() {
if ( is_callable( [ self::$extend, 'register_endpoint_data' ] ) ) {
self::$extend->register_endpoint_data(
[
'endpoint' => CheckoutSchema::IDENTIFIER,
'namespace' => self::IDENTIFIER,
'schema_callback' => [ 'Custom_Inner_Block_Extend_Store_Endpoint', 'extend_checkout_schema' ],
'schema_type' => ARRAY_A,
]
);
}
}
新字段块
/** * 将新的字段块结构化数据注册到结账端点。 * * @return array 注册的结构化数据。 * */ public static function extend_checkout_schema() { return [ 'Value_1' => [ 'description' => '字段的描述', 'type' => 'string', // ... 字段的类型,应该是一个字符串 'context' => [ 'view', 'edit' ], // ... 字段的上下文,应该是一个包含 'view' 和 'edit' 的数组 'readonly' => true, // ... 字段是否为只读,应该是一个布尔值 'optional' => true, // ... 字段是否为可选,应该是一个布尔值 ], // ... 其他值 ]; } }
- `new-field-block.php` 文件:主插件文件,加载 `custom-inner-block-blocks-integration.php` 和 `custom-inner-block-extend-store-endpoint.php` 文件。
```php
<?php
/**
* 插件名称: New Field Block
* 版本: 1.0
* 作者: Your Name Here
* 许可证: GPL-2.0-or-later
* 许可证 URI: https://www.gnu.org/licenses/gpl-2.0.html
* 文本域: new-field-block
*
* @package create-block
*/
// ... 一些代码
/**
* 包含实例化块所需的依赖项。
*/
add_action(
'woocommerce_blocks_loaded',
function() {
require_once __DIR__ . '/custom-inner-block-blocks-integration.php';
// 当 WC Blocks 加载时,初始化我们的商店端点扩展。
Custom_Inner_Block_Extend_Store_Endpoint::init();
add_action(
'woocommerce_blocks_checkout_block_registration',
function( $integration_registry ) {
$integration_registry->register( new Custom_Inner_Block_Blocks_Integration() );
}
);
}
);
// ... 一些代码
以下是一个示例,来自我们的 教程,说明如何在处理结账时获取此自定义字段的数据。 此示例来自 shipping-workshop-blocks-integration.php 文件。 完整的代码可以在此 GitHub 仓库 中找到。
# 配送说明保存
本节介绍如何保存配送说明。
我们使用一个钩子,即 `woocommerce_store_api_checkout_update_order_from_request` 操作,该操作会将配送工作坊的替代配送说明更新到订单元数据中。
该钩子的文档位于:https://github.com/woocommerce/woocommerce-blocks/blob/b73fbcacb68cabfafd7c3e7557cf962483451dc1/docs/third-party-developers/extensibility/hooks/actions.md#woocommerce_store_api_checkout_update_order_from_request
```php
private function save_shipping_instructions() {
/**
* We write a hook, using the `woocommerce_store_api_checkout_update_order_from_request` action
* that will update the order metadata with the shipping-workshop alternate shipping instruction.
*
* The documentation for this hook is at: https://github.com/woocommerce/woocommerce-blocks/blob/b73fbcacb68cabfafd7c3e7557cf962483451dc1/docs/third-party-developers/extensibility/hooks/actions.md#woocommerce_store_api_checkout_update_order_from_request
*/
add_action(
'woocommerce_store_api_checkout_update_order_from_request',
function( \WC_Order $order, \WP_REST_Request $request ) {
$shipping_workshop_request_data = $request['extensions'][$this->get_name()];
$alternate_shipping_instruction = $shipping_workshop_request_data['alternateShippingInstruction'];
$other_shipping_value = $shipping_workshop_request_data['otherShippingValue'];
$order->update_meta_data( 'shipping_workshop_alternate_shipping_instruction', $alternate_shipping_instruction );
$order->save();
},
10,
2
);
}
说明:
woocommerce_store_api_checkout_update_order_from_request:这是一个操作钩子,用于在结账更新订单时执行自定义操作。\WC_Order $order:表示订单对象。\WP_REST_Request $request:表示请求对象。$request['extensions'][$this->get_name()]:从请求中获取扩展数据。$order->update_meta_data():更新订单的元数据。$order->save():保存订单。
使用方法:
- 确保已安装并激活相应的扩展。
- 在
checkout页面,用户可以输入替代配送说明。 - 当用户完成结账时,替代配送说明将被保存到订单的元数据中。
注意事项:
- 请确保您的扩展与 WooCommerce API 兼容。
- 在更新订单元数据之前,请务必进行数据验证。
其他信息:
- 您可以在
Store的Order详情页面查看保存的配送说明。 Data存储在订单的元数据中。- 如果需要修改保存的
Value,请使用API或Hooks。 - 请定期
check您的API和Extensions,以确保其正常运行。 - 如果遇到问题,请联系
Developers寻求帮助。 Shipping信息将影响Shipping费用。Actions决定了订单的处理流程。Request包含了用户提交的数据。Date记录了订单的创建和更新时间。Save操作会将数据持久化到数据库。Lock功能可以防止多个用户同时修改订单。Shop平台提供各种购物体验。Document提供了详细的使用说明。API提供了编程接口。Hooks允许您自定义 WooCommerce 的行为。
## 结论
通过遵循以上步骤,您可以新增和处理新的字段区块,从而在 WooCommerce 结账区块中添加自定义的配送选项。有关完整实现和更多例子,请参考提供的 [教程](https://developer.woocommerce.com/2023/08/07/extending-the-woocommerce-checkout-block-to-add-custom-shipping-options/) 和相应的 [GitHub 仓库](https://github.com/woocommerce/wceu23-shipping-workshop-final/)。
暴露你的数据
问题
您希望扩展 Mini-Cart、Cart 和 Checkout 模块,但需要使用一些 Store API 或上下文环境中不可用的自定义数据。您不想创建自己的 API 接口或 Ajax 操作,而是希望利用现有的 StoreAPI 调用。
解决方案
ExtendSchema 提供了将上下文自定义数据添加到 Store API 接口的可能性,例如 wc/store/cart 和 wc/store/cart/items 接口。这些数据会被限定在您的插件命名空间内,并受到保护,防止其他插件导致其功能异常。这些数据在所有前端过滤器和 slotFills 中都可用,供您使用。
基本用法
您可以通过注册两个函数,schema_callback 和 data_callback,在特定的接口命名空间中使用 ExtendSchema。ExtendSchema 将在执行时调用这些函数,并将相关数据传递给它们。
以下示例使用 Cart 接口,请参阅已传递的参数。
注意:请务必阅读下面的“注意事项”部分。
use Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema;
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => CartSchema::IDENTIFIER,
'namespace' => 'plugin_namespace',
'data_callback' => 'my_data_callback',
'schema_callback' => 'my_schema_callback',
'schema_type' => ARRAY_A,
)
);
});
function my_data_callback() {
return [
'custom-key' => 'custom-value',
];
}
function my_schema_callback() {
return [
'custom-key' => [
'description' => __( 'My custom data', 'plugin-namespace' ),
'type' => 'string',
'readonly' => true,
]
];
}
数据回调函数和 Schema 回调函数也可以接收参数:
function my_cart_item_callback( $cart_item ) {
$product = $cart_item['data'];
if ( is_my_custom_product_type( $product ) ) {
$custom_value = get_custom_value( $product );
return [
'custom-key' => $custom_value,
];
}
}
注意事项
ExtendSchema 是一个共享实例
ExtendSchema 被存储为 API 和客户端(第三方开发者)之间的共享实例。因此,您不应该使用 new ExtendSchema 手动创建该类的实例,因为它可能无法正常工作。相反,您应该始终从 StoreApi 依赖注入容器中获取共享实例,例如:
$extend = StoreApi::container()->get( ExtendSchema::class );
请注意,依赖注入容器只有在 woocommerce_blocks_loaded 动作被触发之后才可用。因此,您应该将您的文件与该动作进行关联:
use Automattic\WooCommerce\StoreApi\StoreApi;
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;
add_action( 'woocommerce_blocks_loaded', function() {
$extend = StoreApi::container()->get( ExtendSchema::class );
// 我的逻辑。
});
或者,您可以使用全局辅助函数:
woocommerce_store_api_register_endpoint_data( $args )woocommerce_store_api_register_update_callback( $args )woocommerce_store_api_register_payment_requirements( $args )woocommerce_store_api_get_formatter( $name )
错误和致命错误对非管理员用户是静默的
如果您的回调函数 data_callback 和 schema_callback 抛出异常或错误,或者您传递了不正确的参数类型给 register_endpoint_data,那么该错误将被捕获并记录到 WooCommerce 错误日志中。如果当前用户是商店管理员或管理员,并且启用了 WP_DEBUG,则该错误将显示在前端。
回调函数应始终返回一个数组
为了减少破坏客户端代码或传递错误类型的可能性,并保持一致的 REST API 响应,诸如 data_callback 和 schema_callback 这样的回调函数应始终返回一个数组,即使该数组为空。
API 定义
ExtendSchema::register_endpoint_data: 用于将数据注册到自定义端点。它接受一个参数数组:
| 属性 | 类型 | 是否必须 | 描述 |
|---|---|---|---|
endpoint |
字符串 | 是 | 您正在扩展的端点。建议您使用路由结构化数据类中的 ::IDENTIFIER 可用属性,以避免拼写错误。 |
namespace |
字符串 | 是 | 您的插件命名空间,数据将在 Store API 响应中位于此命名空间下。 |
data_callback |
回调函数 | 是 | 一个返回包含您数据的数组的回调函数。 |
schema_callback |
回调函数 | 是 | 一个返回您的数据形状的回调函数。 |
schema_type |
字符串 | 否 (默认值: ARRAY_A ) |
您的数据类型。如果您正在添加一个对象(键 => 值),则应为 ARRAY_A。如果您正在添加一个项目列表,则应为 ARRAY_N。 |
整合所有内容
这是一个完整的示例,展示了如何在每个购物车项中注册与 WooCommerce 订阅相关的结构化数据(简化版)。 此示例使用 Formatters,这些是实用类,允许您格式化值,使其与 StoreAPI 兼容。
<?php
/**
* WooCommerce 订阅 Extend Store API。
*
* 一个类,用于扩展公共 API,为每个订阅项添加相关的订阅数据。
*
* @package WooCommerce 订阅
*/
use Automattic\WooCommerce\StoreApi\StoreApi;
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;
use Automattic\WooCommerce\StoreApi\Schemas\V1\CartItemSchema;
add_action( 'woocommerce_blocks_loaded', function() {
$extend = StoreApi::container()->get( ExtendSchema::class );
WC_Subscriptions_Extend_Store_Endpoint::init( $extend );
});
class WC_Subscriptions_Extend_Store_Endpoint {
/**
* 存储 Rest Extending 实例。
*
* @var ExtendSchema
*/
private static $extend;
/**
* 插件标识符,每个插件独一无二。
*
* @var string
*/
const IDENTIFIER = 'subscriptions';
/**
* 启动类并挂载所需的数据。
*
* @param ExtendSchema $extend_rest_api ExtendSchema 类的实例。
*
* @since 3.1.0
*/
public static function init( ExtendSchema $extend_rest_api ) {
self::$extend = $extend_rest_api;
self::extend_store();
}
/**
* 注册实际数据到每个端点。
*/
public static function extend_store() {
// 注册到 `cart/items`
self::$extend->register_endpoint_data(
array(
'endpoint' => CartItemSchema::IDENTIFIER,
'namespace' => self::IDENTIFIER,
'data_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_item_data' ),
'schema_callback' => array( 'WC_Subscriptions_Extend_Store_Endpoint', 'extend_cart_item_schema' ),
'schema_type' => ARRAY_A,
)
);
}
/**
* 将订阅产品数据注册到 cart/items 端点。
*
* @param array $cart_item 当前购物车项数据。
*
* @return array $item_data 注册的数据,如果条件不满足则返回空数组。
*/
public static function extend_cart_item_data( $cart_item ) {
$product = $cart_item['data'];
$item_data = array(
'billing_period' => null,
'billing_interval' => null,
'subscription_length' => null,
'trial_length' => null,
'trial_period' => null,
'sign_up_fees' => null,
'sign_up_fees_tax' => null,
);
# 注册产品变体
本节描述如何处理注册产品变体。
## 注册产品变体
注册产品变体时,需要考虑以下因素:
* **变体**:每个变体都必须具有唯一的标识符。
* **结构化数据**:每个变体都必须具有有效的结构化数据。
* **字符串**:产品名称和描述必须是有效的字符串。
* **订阅**:如果产品是订阅产品,则必须设置订阅周期和间隔。
* **注册**:每个用户都必须注册才能购买产品。
* **下标**:产品价格必须使用正确的下标。
* **只读**:某些产品属性是只读的,不能被修改。
* **上下文**:产品信息必须在正确的上下文中显示。
* **产品**:每个产品都必须具有唯一的标识符。
* **格式**:产品价格必须使用正确的格式。
* **长度**:产品名称和描述的长度必须在允许的范围内。
* **注册**:用户必须注册才能购买产品。
* **数值**:产品价格必须是有效的数值。
* **合并**:如果产品包含多个变体,则必须将它们合并为一个产品。
* **数据**:产品数据必须是有效的。
* **编辑**:用户可以编辑某些产品属性。
* **购物车**:用户可以将产品添加到购物车。
* **项目**:每个产品都是一个项目。
* **红色**:产品颜色可以是红色。
```php
if ( in_array( $product->get_type(), array( 'subscription', 'subscription_variation' ), true ) ) {
$item_data = array_merge(
array(
'billing_period' => WC_Subscriptions_Product::get_period( $product ),
'billing_interval' => (int) WC_Subscriptions_Product::get_interval( $product ),
'subscription_length' => (int) WC_Subscriptions_Product::get_length( $product ),
'trial_length' => (int) WC_Subscriptions_Product::get_trial_length( $product ),
'trial_period' => WC_Subscriptions_Product::get_trial_period( $product ),
),
self::format_sign_up_fees( $product )
);
}
return $item_data;
}
/**
* Register subscription product schema into cart/items endpoint.
*
* @return array Registered schema.
*/
public static function extend_cart_item_schema() {
return array(
'billing_period' => array(
'description' => __( 'Billing period for the subscription.', 'woocommerce-subscriptions' ),
'type' => array( 'string', 'null' ),
'enum' => array_keys( wcs_get_subscription_period_strings() ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'billing_interval' => array(
'description' => __( 'The number of billing periods between subscription renewals.', 'woocommerce-subscriptions' ),
'type' => array( 'integer', 'null' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'subscription_length' => array(
'description' => __( 'Subscription Product length.', 'woocommerce-subscriptions' ),
'type' => array( 'integer', 'null' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'trial_period' => array(
'description' => __( 'Subscription Product trial period.', 'woocommerce-subscriptions' ),
'type' => array( 'string', 'null' ),
'enum' => array_keys( wcs_get_subscription_period_strings() ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'trial_length' => array(
'description' => __( 'Subscription Product trial interval.', 'woocommerce-subscriptions' ),
'type' => array( 'integer', 'null' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'sign_up_fees' => array(
'description' => __( 'Subscription Product signup fees.', 'woocommerce-subscriptions' ),
'type' => array( 'string', 'null' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'sign_up_fees_tax' => array(
'description' => __( 'Subscription Product signup fees taxes.', 'woocommerce-subscriptions' ),
'type' => array( 'string', 'null' ),
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
);
}
/**
* 格式化注册费用。
*
* @param \WC_Product $product 当前产品。
* @return array
*/
private static function format_sign_up_fees( $product ) {
$fees_excluding_tax = wcs_get_price_excluding_tax(
$product,
array(
'qty' => 1,
'price' => WC_Subscriptions_Product::get_sign_up_fee( $product ),
)
);
$fees_including_tax = wcs_get_price_including_tax(
$product,
array(
'qty' => 1,
'price' => WC_Subscriptions_Product::get_sign_up_fee( $product ),
)
);
$money_formatter = self::$extend->get_formatter( 'money' );
return array(
'sign_up_fees' => $money_formatter->format(
$fees_excluding_tax
),
'sign_up_fees_tax' => $money_formatter->format(
$fees_including_tax
- $fees_excluding_tax
),
);
}
}
格式化您的数据
您可能希望使用我们预先存在的格式化工具(Formatters),以确保您的数据以正确的格式通过 API。关于格式化工具的更多信息,请参阅 StoreApi 格式化工具 文档。
可用的格式化器
Formatters 是实用类,允许您格式化值,使其与 Store API 兼容。 默认格式化器处理诸如货币金额、货币信息或 HTML 之类的数值。
建议您在扩展 Store API 时使用这些格式化器。
为什么格式化器很有用?
使用格式化器实用程序返回某些类型的数据,可以确保您的自定义数据与 Store API 的其他接口保持一致和兼容。 它们还处理任何可能影响数据格式化的商店特定设置,例如货币设置。
Store API 包含以下格式化器:
如何使用格式化器
要获取格式化器,可以使用 ExtendSchema 类的 get_formatter 方法。 此方法接受一个字符串,即您想要使用的格式化器的名称。
get_formatter('money'); // 用于 MoneyFormatter
get_formatter('html'); // 用于 HtmlFormatter
get_formatter('currency'); // CurrencyFormatter
这将返回一个 FormatterInterface 对象,该对象具有 format 方法。 format 方法的签名如下:
format( $value, array $options = [] );
只有 MoneyFormatter 的行为可以通过 $options 参数进行控制。 此参数是可选的。
实际示例
假设我们要通过 API 返回一些额外的价格数据。 我们希望以美分形式返回价格,以及商店的货币数据。 我们可以使用 MoneyFormatter 和 CurrencyFormatter 来实现此目的。
首先,我们需要确保可以访问格式化器类。 我们可以使用 use 关键字来实现:
use Automattic\WooCommerce\StoreApi\StoreApi;
use Automattic\WooCommerce\StoreApi\Utilities\ExtendSchema;
$extend = StoreApi::container()->get( ExtendSchema::class );
$my_custom_price = $extend->get_formatter( 'money' )->format( '10.00', [
'rounding_mode' => PHP_ROUND_HALF_DOWN,
'decimals' => 2
] );
$price_response = $extend->get_formatter( 'currency' )->format( [
'price' => $my_custom_price,
] );
上述代码将使 $price_response 设置为:
[
'price' => '1000'
'currency_code' => 'GBP'
'currency_symbol' => '£'
'currency_minor_unit' => 2
'currency_decimal_separator' => '.'
'currency_thousand_separator' => ','
'currency_prefix' => '£'
'currency_suffix' => ''
]
MoneyFormatter
[MoneyFormatter](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/src/StoreApi/Formatters/MoneyFormatter.php) 类可用于使用商店的 设置 格式化 货币 价值。 商店的 设置 可以通过将 选项 传递给此格式化器的 format 方法 来覆盖。
为了避免浮点数舍入错误,返回值以“分”为单位。 因此,在使用此格式化器时,您很可能还会使用 [CurrencyFormatter](#currencyformatter) 同时返回 货币 数据,以便 API 的使用者能够以预期的 格式 显示 价值。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
$value |
number |
要格式化为 货币 值的数值。 |
$options |
array |
应该包含两个键,decimals,它应该是一个 integer。 |
$options['decimals'] |
number |
用于控制 货币 值中应显示多少位小数。 默认为商店的 设置。 |
$options['rounding_mode'] |
number |
用于确定如何对 货币 值进行四舍五入。 这应该是 PHP 四舍五入模式之一,如 PHP round() 文档 中所述。 默认为 PHP_ROUND_HALF_UP。 |
示例用法和返回值
get_formatter( 'money' )->format( 10.443, [
'rounding_mode' => PHP_ROUND_HALF_DOWN,
'decimals' => 2
] );
返回 1044
CurrencyFormatter
这个格式化器接收一个价格数组,并返回相同的数组,但附加了货币数据。添加的货币数据如下:
| 键 | 类型 | 描述 |
|---|---|---|
currency_code |
string |
货币的字符串表示,例如:GBP 或 USD |
currency_symbol |
string |
货币的符号,例如:£ 或 $ |
currency_minor_unit |
number |
货币显示的十进制位数 |
currency_decimal_separator |
string |
用于分隔货币中整数部分和小数部分的字符串。 |
currency_thousand_separator |
string |
用于分隔货币中千位数的字符串,例如:£10,000 或 €10.000 |
currency_prefix |
string |
应该出现在货币值之前的字符串。 |
currency_suffix |
string |
应该出现在货币值之后的字符串。 |
然后,客户端/消费者可以使用这些数据,根据商店的设置正确地格式化价格。重要:传递给此格式化器的价格数组应该已经处于货币格式,因此您应该首先使用 MoneyFormatter。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
$value |
number[] |
要与商店的货币设置合并的价格数组 |
示例用法和返回的值
get_formatter( 'currency' )->format( [
'price' => 1800,
'regular_price' => 1800,
'sale_price' => 1800,
] );
返回
'price' => '1800'
'regular_price' => '1800'
'sale_price' => '1800'
'price_range' => null
'currency_code' => 'GBP'
'currency_symbol' => '£'
'currency_minor_unit' => 2
'currency_decimal_separator' => '.'
'currency_thousand_separator' => ','
'currency_prefix' => '£'
'currency_suffix' => ''
HtmlFormatter
这个格式化器会接收一个 HTML 字符串,并对其进行以下处理:wptexturize、convert_chars、trim 和 wp_kses_post,然后再返回结果。这个格式化器的目的是使 HTML 变得“安全”(即,正确地格式化了字符)。wp_kses_post 会确保只允许在 post 上下文中使用的 HTML 标签出现在字符串中。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
$value |
string |
您想要格式化成“安全”HTML 的字符串。 |
使用示例和返回的值
get_formatter( 'html' )->format(
"<script>alert('bad script!')</script> This \"coffee\" is <strong>very strong</strong>."
);
返回:
alert('bad script!') This “coffee” is <strong>very strong</strong>.
无论 HTML 是由用户生成还是其他方式生成,都应该在从 StoreAPI 返回 HTML 时使用此格式化器。这可以确保客户端/消费者能够安全地显示 HTML,并且不会出现编码问题。
动态更新购物车
问题
您是一位扩展开发者,您的扩展在客户端输入(例如,购物者在购物车侧边栏的输入框中填写内容,然后点击一个按钮)的触发下,执行一些服务器端处理。
这种服务器端处理会导致购物车状态发生变化,您希望更新客户端购物车或结账模块中显示的数据。
您不能直接更新客户端购物车状态。这是为了防止功能出现问题的扩展意外地使用格式错误或无效的数据更新它,这会导致整个模块崩溃。
解决方案
ExtendSchema 提供了扩展注册回调函数的机制,这些函数将在客户端购物车或结账模块发出信号时执行。
WooCommerce Blocks 还提供一个名为 extensionCartUpdate 的前端函数,客户端代码可以调用它。这将向 cart/extensions 端点发送数据(您在调用 extensionCartUpdate 时指定)。当该端点被访问时,会执行所有相关的回调函数(基于传递给 extensionCartUpdate 的命名空间),然后将最新的服务器端购物车数据返回,并使用这些新数据更新模块。
基本用法
在您的扩展的服务器端集成代码中:
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_update_callback(
[
'namespace' => 'extension-unique-namespace',
'callback' => /* 在此处添加您的可调用函数 */
]
);
} );
在客户端:
const { extensionCartUpdate } = wc.blocksCheckout;
const { processErrorResponse } = wc.wcBlocksData;
extensionCartUpdate( {
namespace: 'extension-unique-namespace',
data: {
key: 'value',
another_key: 100,
third_key: {
fourth_key: true,
},
},
} ).then( () => {
// 购物车已更新。
} ).catch( ( error ) => {
// 处理错误。
processErrorResponse(error);
} );
需要注意的事项
扩展不能直接更新客户端购物车状态
您可能想知道为什么不能为您的扩展创建一个自定义的 AJAX 端点来更新购物车。如前所述,扩展不允许直接更新客户端购物车的状态,因为这样做不正确会导致整个模块崩溃,从而阻止用户继续结账。相反,您_必须_通过 extensionCartUpdate 函数来执行此操作。
对于给定的命名空间,只能注册一个回调函数
考虑到这一点,如果您的扩展程序有多个客户端交互,导致服务器端执行不同的代码路径,您可能希望通过 extensionCartUpdate 函数传递额外的 数据。例如,如果用户可以执行两个 操作,一个用于添加 折扣,另一个用于移除 折扣,您可能希望将一个名为 action 的键以及其他 数据 一起传递给 extensionCartUpdate 函数。然后在您的回调函数中,您可以检查此 价值 以区分应该执行哪个代码路径。
示例:
<?php
function add_discount() {
/* 在此处执行一些处理 */
}
function remove_discount() {
/* 在此处执行一些处理 */
}
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_update_callback(
[
'namespace' => 'extension-unique-namespace',
'callback' => function( $data ) {
if ( $data['action'] === 'add' ) {
add_discount( );
}
if ( $data['action'] === 'remove' ) {
remove_discount();
}
}
]
);
} );
如果您尝试在相同的命名空间下再次 注册,则先前 注册 的回调函数将被覆盖。
API 定义
PHP
ExtendSchema::register_update_callback: 用于注册一个回调函数,当 cart/extensions 接口接收到指定命名空间的数据时,该回调函数会被执行。它接收一个参数数组。
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
namespace |
string |
是 | 您的扩展的命名空间。 这用于确定应该执行哪个扩展的回调函数。 |
callback |
Callable |
是 | 当 cart/extensions 接口接收到与提供的命名空间匹配的数据时,将要执行的函数/方法(或可调用对象)。 该可调用对象应该接受一个参数。 通过该参数传递给回调函数的数据将是一个数组,其中包含您选择传递的任何数据。 可调用对象不需要返回任何值,如果它返回了值,则该返回值将不被使用。 |
JavaScript
extensionCartUpdate: 用于通知系统,您希望执行已注册的回调函数,并向回调函数传递数据。它接受一个对象作为唯一的参数。
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
namespace |
string |
是 | 您的扩展程序的命名空间。 这用于确定应执行哪个扩展程序的的回调函数。 |
data |
Object |
否 | 您想要传递给回调函数的数据。 data 键中的任何内容都将作为第一个(也是唯一)参数传递给您的回调函数,以关联数组的形式。 |
overwriteDirtyCustomerData |
boolean |
否 | 是否覆盖客户端中的客户数据,使用从服务器返回的数据,即使该数据尚未推送到服务器。 |
综合应用
您是开发一个扩展程序的作者,该扩展程序允许购物者使用他们在您的网站上赚取的积分,以获得其订单的折扣。 存在一个文本字段,购物者可以在其中输入他们想要兑换的积分数量,还有一个提交按钮,用于应用兑换。
您的扩展程序使用 DiscountsMeta 插槽,将这些 UI 元素添加到购物车和结账块的侧边栏中。
有关如何使用插槽的更多信息,请参阅我们的 插槽和填充文档。
实现后,侧边栏会添加一个控件,如下所示:

"兑换" 按钮
在您的 UI 中,您正在使用 React useState 变量跟踪购物者在 "输入金额" 框中输入的值。 在此示例中,该变量应称为 pointsInputValue。
当 "兑换" 按钮被点击时,您需要告诉服务器要将多少积分应用于购物者的购物车,基于他们输入到框中的内容,应用相关的折扣,更新服务器端的购物车,然后将更新后的价格显示在客户端的侧边栏中。
为此,您需要使用 extensionCartUpdate 来告诉服务器您希望执行您的回调函数,并加载新的购物车状态到 UI 中。 按钮的 onClick 处理程序可能如下所示:
const { extensionCartUpdate } = window.wc.blocksCheckout;
const buttonClickHandler = () => {
extensionCartUpdate( {
namespace: 'super-coupons',
data: {
pointsInputValue,
},
} );
};
注册一个回调函数,当 cart/extensions 接口被访问时执行
到目前为止,我们还没有在 WooCommerce Blocks 中注册任何回调函数,因此,当 extensionCartUpdate 触发 cart/extensions 接口时,不会发生任何操作。
类似于向 Store API 添加数据(在 在 Store API 中暴露您的数据 中有更详细的描述),我们可以通过在 WooCommerce Blocks 中的 ExtendSchema 类上调用 register_update_callback 方法来添加回调函数。
我们编写了一个名为 redeem_points 的函数,该函数将折扣应用于 WooCommerce 购物车。 该函数不返回任何值。 请注意,此函数的实际实现不是本文档的重点,因此已省略。 重要的是要注意的是,它会修改 WooCommerce 购物车。
<?php
function redeem_points( $points ) {
/* 在此处进行一些处理,根据 $points 的值将折扣应用于 WC 购物车 */
}
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_update_callback(
[
'namespace' => 'super-coupons',
'callback' => function( $data ) {
redeem_points( $data['points'] );
},
]
);
} );
现在,该回调函数已注册,当按下按钮时,cart/extensions 接口将被访问,并且由于 namespace 为 super-coupons,我们的 redeem_points 函数将被执行。 在此处理完成后,WooCommerce Blocks 将更新客户端购物车。
购物车优惠券 API
获取购物车优惠券列表
GET /cart/coupons
此接口不需要任何参数。
curl "https://example-store.com/wp-json/wc/store/v1/cart/coupons"
示例响应:
[
{
"code": "20off",
"type": "fixed_cart",
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"total_discount": "1667",
"total_discount_tax": "333"
},
"_links": {
"self": [
{
"href": "http://local.wordpress.test/wp-json/wc/store/v1/cart/coupons/20off"
}
],
"collection": [
{
"href": "http://local.wordpress.test/wp-json/wc/store/v1/cart/coupons"
}
]
}
}
]
获取单个购物车优惠券
获取单个购物车优惠券。
GET /cart/coupons/:code
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 要检索的购物车优惠券的优惠券代码。 |
curl "https://example-store.com/wp-json/wc/store/v1/cart/coupons/20off"
示例响应:
{
"code": "halfprice",
"type": "percent",
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"total_discount": "9950",
"total_discount_tax": "0"
}
}
添加购物车优惠券
将优惠券应用于购物车。 如果成功应用,则返回新的优惠券对象;否则,返回错误。
POST /cart/coupons/
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望应用于购物车的优惠券代码。 |
curl --request POST https://example-store.com/wp-json/wc/store/v1/cart/coupons?code=20off
示例响应:
{
"code": "20off",
"type": "percent",
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"total_discount": "1667",
"total_discount_tax": "333"
}
}
删除单个购物车优惠券
删除/移除购物车中的优惠券。
DELETE /cart/coupons/:code
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望从购物车中移除的优惠券代码。 |
curl --request DELETE https://example-store.com/wp-json/wc/store/v1/cart/coupons/20off
删除购物车中的所有优惠券
删除/移除购物车中的所有优惠券。
DELETE /cart/coupons/
这个接口不需要任何参数。
curl --request DELETE https://example-store.com/wp-json/wc/store/v1/cart/coupons
例子回复:
[]
购物车项目 API
本 API 提供了访问和管理购物车项目的接口。
功能描述:
该 API 允许您:
- 获取购物车中的所有项目: 可以根据用户 ID 或购物车 ID 获取指定购物车中的所有项目列表。
- 添加项目到购物车: 可以向指定购物车中添加新的项目。
- 更新购物车中的项目: 可以修改购物车中现有项目的数量或价格。
- 从购物车中删除项目: 可以从指定购物车中移除特定的项目。
API 端点:
GET /api/cart/%s/items: 获取指定购物车中的所有项目。POST /api/cart/%s/items: 向指定购物车中添加新的项目。PUT /api/cart/%s/items/%d: 更新指定购物车中的项目。DELETE /api/cart/%s/items/%d: 从指定购物车中删除项目。
请求参数:
| 参数名 | 类型 | 描述 | 必填 |
|---|---|---|---|
| cart_id | string | 购物车 ID | 是 |
| item_id | integer | 项目 ID | 是 |
| quantity | integer | 项目数量 | 否 |
| price | float | 项目价格 | 否 |
| name | string | 项目名称 | 否 |
| description | string | 项目描述 | 否 |
响应格式:
{
"status": "success",
"data": [
{
"item_id": %d,
"name": "{name}",
"quantity": %d,
"price": %.2f
}
]
}
错误处理:
如果发生错误,API 将返回以下错误代码:
400 Bad Request: 请求参数无效。404 Not Found: 购物车或项目未找到。500 Internal Server Error: 服务器内部错误。
示例:
-
获取购物车中的所有项目:
curl -X GET http://localhost:8000/api/cart/user123/items -
向购物车中添加新的项目:
curl -X POST http://localhost:8000/api/cart/user123/items \ -H "Content-Type: application/json" \ -d '{ "item_id": 1, "quantity": 2, "price": 10.00 }'
注意:
- 请确保您已正确配置 API 密钥,以便访问该 API。
- 请参考 API 文档以获取更多详细信息。
购物车项目列表
GET /cart/items
使用此接口不需要额外的参数。
curl "https://example-store.com/wp-json/wc/store/v1/cart/items"
例子回复:
[
{
"key": "c74d97b01eae257e44aa9d5bade97baf",
"id": 16,
"quantity": 1,
"type": "simple",
"quantity_limits": {
"minimum": 1,
"maximum": 1,
"multiple_of": 1,
"editable": false
},
"name": "Beanie",
"short_description": "<p>这是一个简单的产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-beanie",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": true,
"permalink": "https://store.local/product/beanie/",
"images": [
{
"id": 45,
"src": "https://store.local/wp-content/uploads/2023/01/beanie-2.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2023/01/beanie-2-450x450.jpg",
"srcset": "https://store.local/wp-content/uploads/2023/01/beanie-2.jpg 801w, https://store.local/wp-content/uploads/2023/01/beanie-2-450x450.jpg 450w, https://store.local/wp-content/uploads/2023/01/beanie-2-100x100.jpg 100w, https://store.local/wp-content/uploads/2023/01/beanie-2-600x600.jpg 600w, https://store.local/wp-content/uploads/2023/01/beanie-2-300x300.jpg 300w, https://store.local/wp-content/uploads/2023/01/beanie-2-150x150.jpg 150w, https://store.local/wp-content/uploads/2023/01/beanie-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "beanie-2.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "1800",
"regular_price": "2000",
"sale_price": "1800",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "18000000",
"regular_price": "20000000",
"sale_price": "18000000"
}
},
"totals": {
"line_subtotal": "1800",
"line_subtotal_tax": "360",
"line_total": "1800",
"line_total_tax": "360",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {},
"_links": {
"self": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items/c74d97b01eae257e44aa9d5bade97baf"
}
],
"collection": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items"
}
]
}
},
{
"key": "e03e407f41901484125496b5ec69a76f",
"id": 29,
"quantity": 1,
"type": "variation",
"quantity_limits": {
"minimum": 1,
"maximum": 9999,
"multiple_of": 1,
"editable": true
},
"name": "Hoodie",
"short_description": "",
"description": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.</p>",
"sku": "woo-hoodie-red",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://store.local/product/hoodie/?attribute_pa_color=red&attribute_logo=No",
"images": [
{
"id": 40,
"src": "https://store.local/wp-content/uploads/2023/01/hoodie-2.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2023/01/hoodie-2-450x450.jpg",
"srcset": "https://store.local/wp-content/uploads/2023/01/hoodie-2.jpg 801w, https://store.local/wp-content/uploads/2023/01/hoodie-2-450x450.jpg 450w, https://store.local/wp-content/uploads/2023/01/hoodie-2-100x100.jpg 100w, https://store.local/wp-content/uploads/2023/01/hoodie-2-600x600.jpg 600w, https://store.local/wp-content/uploads/2023/01/hoodie-2-300x300.jpg 300w, https://store.local/wp-content/uploads/2023/01/hoodie-2-150x150.jpg 150w, https://store.local/wp-content/uploads/2023/01/hoodie-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "hoodie-2.jpg",
"alt": ""
}
],
"variation": [
{
"raw_attribute": "attribute_pa_color",
"attribute": "颜色",
"value": "红色"
},
{
"raw_attribute": "attribute_logo",
"attribute": "徽章",
"value": "无"
}
],
"item_data": [],
"prices": {
"price": "4200",
"regular_price": "4500",
"sale_price": "4200",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "42000000",
"regular_price": "45000000",
"sale_price": "42000000"
}
},
"totals": {
"line_subtotal": "4200",
"line_subtotal_tax": "840",
"line_total": "4200",
"line_total_tax": "840",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {},
"_links": {
"self": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items/e03e407f41901484125496b5ec69a76f"
}
],
"collection": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items"
}
]
}
}
]
单个购物车项目
通过其关键字获取单个购物车项目。
GET /cart/items/:key
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要检索的购物车项目的关键字。 |
curl "https://example-store.com/wp-json/wc/store/v1/cart/items/c74d97b01eae257e44aa9d5bade97baf"
例子回复:
{
"key": "c74d97b01eae257e44aa9d5bade97baf",
"id": 16,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 1,
"multiple_of": 1,
"editable": false
},
"name": "Beanie",
"short_description": "<p>这是一个简单产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-beanie",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": true,
"permalink": "https://store.local/product/beanie/",
"images": [
{
"id": 45,
"src": "https://store.local/wp-content/uploads/2023/01/beanie-2.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2023/01/beanie-2-450x450.jpg",
"srcset": "https://store.local/wp-content/uploads/2023/01/beanie-2.jpg 801w, https://store.local/wp-content/uploads/2023/01/beanie-2-450x450.jpg 450w, https://store.local/wp-content/uploads/2023/01/beanie-2-100x100.jpg 100w, https://store.local/wp-content/uploads/2023/01/beanie-2-600x600.jpg 600w, https://store.local/wp-content/uploads/2023/01/beanie-2-300x300.jpg 300w, https://store.local/wp-content/uploads/2023/01/beanie-2-150x150.jpg 150w, https://store.local/wp-content/uploads/2023/01/beanie-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "beanie-2.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "1800",
"regular_price": "2000",
"sale_price": "1800",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "18000000",
"regular_price": "20000000",
"sale_price": "18000000"
}
},
"totals": {
"line_subtotal": "1800",
"line_subtotal_tax": "360",
"line_total": "1800",
"line_total_tax": "360",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {},
"_links": {
"self": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items/(?P<key>[\\w-]{32})/c74d97b01eae257e44aa9d5bade97baf"
}
],
"collection": [
{
"href": "https://store.local/wp-json/wc/store/v1/cart/items/(?P<key>[\\w-]{32})"
}
]
}
}
添加购物车项目
将项目添加到购物车。返回已添加的新购物车项目,或错误响应。
POST /cart/items/
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
整数 | 是 | 购物车项目的产品或变体 ID。 |
quantity |
整数 | 是 | 购物车中此项目的数量。 |
variation |
数组 | 是 | 选择的属性(用于变体),包含一个对象数组,其中包含键 attribute 和 value。 |
curl --request POST https://example-store.com/wp-json/wc/store/v1/cart/items?id=100&quantity=1
有关示例响应,请参阅 单个购物车项目。
如果您想一次性添加多个项目到购物车,请参阅 批量操作。
编辑单个购物车项目
编辑购物车中的项目。
PUT /cart/items/:key
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的键。 |
quantity |
整数 | 是 | 购物车中此项目的数量。 |
curl --request PUT https://example-store.com/wp-json/wc/store/v1/cart/items/e369853df766fa44e1ed0ff613f563bd?quantity=10
有关示例响应,请参阅 单个购物车项目。
删除单个购物车项目
通过其键从购物车中删除项目。
DELETE /cart/items/:key
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的键。 |
curl --request DELETE https://example-store.com/wp-json/wc/store/v1/cart/items/e369853df766fa44e1ed0ff613f563bd
删除所有购物车项目
一次性从购物车中删除所有项目。
DELETE /cart/items/
使用此端点不需要额外的参数。
curl --request DELETE https://example-store.com/wp-json/wc/store/v1/cart/items
示例响应:
[]
购物车 API
购物车 API 返回当前会话或已登录用户的购物车当前状态。
所有 POST 接口都需要一个 随机数 Token 或一个 购物车 Token,并在完成时返回完整的购物车更新后的状态。
获取购物车
GET /cart
此接口不需要任何参数。
curl "https://example-store.com/wp-json/wc/store/v1/cart"
返回完整的购物车对象回复(参见 购物车回复)。
回复
/cart 下的所有接口(如本文档中所列)都以相同的格式返回回复:一个购物车对象,其中包含购物车项目、已应用的优惠券、配送地址和费率,以及非敏感的客户数据。
购物车回复
本节描述了购物车相关的回复。
请求参数:
cart_id: 购物车ID (整数)user_id: 用户ID (整数)
请求示例:
GET /api/v1/cart/%s?user_id=%d
回复格式:
{
"status": "success",
"data": {
"cart_id": %d,
"user_id": %d,
"items": [
{
"product_id": %d,
"quantity": %d
}
]
}
}
错误代码:
| 代码 | 描述 |
|---|---|
| 400 | 错误的请求参数。 |
| 401 | 未授权。 |
| 404 | 购物车不存在。 |
| 500 | 服务器内部错误。 |
示例回复:
{
"status": "success",
"data": {
"cart_id": 123,
"user_id": 456,
"items": [
{
"product_id": 789,
"quantity": 2
}
]
}
}
错误回复示例:
{
"status": "error",
"code": 404,
"message": "Cart not found."
}
注意事项:
status字段表示请求是否成功。data字段包含购物车信息。code字段表示错误代码。message字段包含错误信息。
其他:
on状态表示购物车已启用。off状态表示购物车已禁用。
函数:
get_cart_response(cart_id, user_id): 获取购物车回复。create_cart(user_id): 创建新的购物车。update_cart_item(cart_id, product_id, quantity): 更新购物车中的商品数量。delete_cart_item(cart_id, product_id): 从购物车中删除商品。clear_cart(cart_id): 清空购物车。
{
"items": [
{
"key": "a5771bce93e200c36f7cd9dfd0e5deaa",
"id": 38,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 9999,
"multiple_of": 1,
"editable": true
},
"name": "带有Logo的帽子",
"short_description": "<p>这是一个简单的产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "Woo-beanie-logo",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/beanie-with-logo/",
"images": [
{
"id": 61,
"src": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-450x450.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-450x450.jpg 450w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-600x600.jpg 600w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "beanie-with-logo-1.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "1800",
"regular_price": "2000",
"sale_price": "1800",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "18000000",
"regular_price": "20000000",
"sale_price": "18000000"
}
},
"totals": {
"line_subtotal": "1800",
"line_subtotal_tax": "180",
"line_total": "1530",
"line_total_tax": "153",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {}
},
{
"key": "b6d767d2f8ed5d21a44b0e5886680cb9",
"id": 22,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 9999,
"multiple_of": 1,
"editable": true
},
"name": "腰带",
"short_description": "<p>这是一个简单的产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-belt",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/belt/",
"images": [
{
"id": 51,
"src": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-450x450.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2.jpg 801w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-450x450.jpg 450w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-600x600.jpg 600w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "belt-2.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "5500",
"regular_price": "6500",
"sale_price": "5500",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "55000000",
"regular_price": "65000000",
"sale_price": "55000000"
}
},
"totals": {
"line_subtotal": "5500",
"line_subtotal_tax": "550",
"line_total": "4675",
"line_total_tax": "468",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {}
}
],
"coupons": [
{
"code": "test",
"discount_type": "percent",
"totals": {
"total_discount": "1095",
"total_discount_tax": "109",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
}
}
],
"fees": [],
"totals": {
"total_items": "7300",
"total_items_tax": "730",
"total_fees": "0",
"total_fees_tax": "0",
"total_discount": "1095",
"total_discount_tax": "110",
"total_shipping": "1300",
"total_shipping_tax": "130",
"total_price": "8256",
"total_tax": "751",
"tax_lines": [
{
"name": "税费",
"price": "751",
"rate": "10%"
}
],
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"shipping_address": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US",
"phone": "123456778"
},
"billing_address": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US",
"email": "checkout@templates.com",
"phone": "123456778"
},
"needs_payment": true,
"needs_shipping": true,
"payment_requirements": [ "products" ],
"has_calculated_shipping": true,
"shipping_rates": [
{
"package_id": 0,
"name": "Shipment 1",
"destination": {
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US"
},
"items": [
{
"key": "a5771bce93e200c36f7cd9dfd0e5deaa",
"name": "带有Logo的帽子",
"quantity": 1
},
{
"key": "b6d767d2f8ed5d21a44b0e5886680cb9",
"name": "腰带",
"quantity": 1
}
],
"shipping_rates": [
{
"rate_id": "flat_rate:10",
"name": "统一费率",
"description": "",
"delivery_time": "",
"price": "1300",
"taxes": "130",
"instance_id": 10,
"method_id": "flat_rate",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": true,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
{
"rate_id": "free_shipping:12",
"name": "免费配送",
"description": "",
"delivery_time": "",
"price": "0",
"taxes": "0",
"instance_id": 12,
"method_id": "free_shipping",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": false,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
{
"rate_id": "local_pickup:13",
"name": "本地自提",
"description": "",
"delivery_time": "",
"price": "0",
"taxes": "0",
"instance_id": 13,
"method_id": "local_pickup",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": false,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
}
]
}
],
"items_count": 2,
"items_weight": 0,
"cross_sells": [],
"errors": [],
"payment_methods": [ "bacs", "cod" ],
"extensions": {}
}
错误回复
如果无法执行购物车操作,将返回一个错误回复。 这将包含一个错误代码和一个错误消息:
{
"code": "woocommerce_rest_cart_invalid_product",
"message": "该产品无法添加到购物车。",
"data": {
"status": 400
}
}
某些错误回复表示冲突(错误 409),例如,当某个项目无法找到或优惠券不再生效时。 当返回此类回复时,服务器的购物车当前状态也会作为错误数据的一部分返回:
{
"code": "woocommerce_rest_cart_invalid_key",
"message": "购物车项目不再存在或无效。",
"data": {
"status": 409,
"cart": { ... }
}
}
这允许客户端在不发出额外请求的情况下,与购物车数据保持同步,即使购物车发生更改或已过期。
添加项目
将项目添加到购物车,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此端点将返回一个错误。
POST /cart/add-item
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer | 是 | 购物车中商品的 ID 或变体 ID。 |
quantity |
integer | 是 | 购物车中此商品的数量。 |
variation |
array | 是 | 选择的属性(用于变体),包含一个对象数组,每个对象包含键 attribute 和 value。 请注意,关于属性命名的说明见下文。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/add-item?id=100&quantity=1
如果成功,则返回完整的 购物车响应;如果失败,则返回一个 错误响应。
如果您希望在将购物车项目数据传递给 CartController::add_to_cart 之前添加补充数据,可以使用 woocommerce_store_api_add_to_cart_data 过滤器。 例如:
add_filter( 'woocommerce_store_api_add_to_cart_data', function( $add_to_cart_data, \WP_REST_Request $request ) {
if ( ! empty( $request['custom-request-param'] ) ) {
$add_to_cart_data['cart_item_data']['custom-request-data'] = sanitize_text_field( $request['custom-request-param'] );
}
return $add_to_cart_data;
}, 10, 2 );
变体属性命名:
在将变体添加到购物车时,属性的命名非常重要。
对于全局属性,发布到 API 的属性应该是属性的别名。 应该有一个 pa_ 前缀。 例如,如果您的属性名为 Color,则别名为 pa_color。
对于特定于产品的属性,发布到 API 的属性可以是以下之一:
- 属性的名称。 例如,如果您的属性名为
Size,则名称为Size。 这对大小写敏感。 - 属性的别名。 例如,如果您的属性名为
Autograph ✏️,则名称为attribute_autograph-%e2%9c%8f%ef%b8%8f。 这对大小写敏感。 您可以从产品页面的相关select中获取此别名。
示例 POST 请求体:
# 添加商品变体到购物车
以下示例向购物车添加了一个商品变体,该变体具有尺寸和颜色等属性。
**批量操作:**
如果您想一次性添加多个项目,则需要使用批量接口:
```http
POST /wc/store/v1/batch
向购物车添加多个项目的 JSON 数据格式如下:
{
"requests": [
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 26,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
},
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 27,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
}
]
}
{
"id": 13,
"quantity": 1,
"variation": [
{
"attribute": "pa_color",
"value": "blue"
},
{
"attribute": "attribute_autograph-%e2%9c%8f%ef%b8%8f",
"value": "Yes"
},
{
"attribute": "Logo",
"value": "Yes"
}
]
}
该示例添加了一个具有尺寸和颜色属性的产品变体到购物车。
Batching:
如果您想一次添加多个项目,您需要使用批量接口:
POST /wc/store/v1/batch
用于向购物车添加多个项目的 JSON 数据如下:
{
"requests": [
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 26,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
},
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 27,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
}
]
}
解释:
Variation: 变体Nonce: 随机数Attribute: 属性Quantity: 数量Requests: 请求Product: 产品Method: 方法Cache: 缓存Color: 颜色Value: 价值Store: 商店Path: 路径Auto: 自动Blue: 蓝色Cart: 购物车Item: 项目Log: 日志and: 和Use: 使用For: 为
移除项目
从购物车中移除一个项目,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此接口将返回一个错误。
POST /cart/remove-item
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的键。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/remove-item?key=e369853df766fa44e1ed0ff613f563bd
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
更新项目
更新购物车中的一个项目,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此接口将返回一个错误。
POST /cart/update-item
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的键。 |
quantity |
整数 | 是 | 购物车中此项目的数量。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/update-item?key=e369853df766fa44e1ed0ff613f563bd&quantity=10
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
应用优惠券
将优惠券应用于购物车,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此接口将返回一个错误。
POST /cart/apply-coupon/
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望应用于购物车的优惠券代码。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/apply-coupon?code=20off
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
移除优惠券
从购物车中移除一个优惠券,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 或 购物车令牌,否则此接口将返回一个错误。
POST /cart/remove-coupon/
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望从购物车中移除的优惠券代码。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/remove-coupon?code=20off
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
更新客户信息
更新客户信息,并返回完整的购物车信息,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此 API 将返回一个错误。
POST /cart/update-customer
客户地址信息
本节描述了客户地址信息的结构。
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
billing_address |
object | 否 | 客户的账单地址。 |
billing_address.first_name |
string | 否 | 客户的名。 |
billing_address.last_name |
string | 否 | 客户的姓氏。 |
billing_address.address_1 |
string | 否 | 配送地址的第一行。 |
billing_address.address_2 |
string | 否 | 配送地址的第二行。 |
billing_address.city |
string | 否 | 配送地址的城市。 |
billing_address.state |
string | 否 | 州、省或地区的 ISO 代码,或名称,用于表示配送地址。 |
billing_address.postcode |
string | 否 | 配送地址的邮政编码。 |
billing_address.country |
string | 否 | 配送地址所在国家的 ISO 代码。 |
billing_address.email |
string | 否 | 客户的邮件地址。 |
billing_address.phone |
string | 否 | 客户的电话号码。 |
shipping_address |
object | 否 | 客户的配送地址。 |
shipping_address.first_name |
string | 否 | 客户的名。 |
shipping_address.last_name |
string | 否 | 客户的姓氏。 |
shipping_address.address_1 |
string | 否 | 配送地址的第一行。 |
shipping_address.address_2 |
string | 否 | 配送地址的第二行。 |
shipping_address.city |
string | 否 | 配送地址的城市。 |
shipping_address.state |
string | 否 | 州、省或地区的 ISO 代码,或名称,用于表示配送地址。 |
shipping_address.postcode |
string | 否 | 配送地址的邮政编码。 |
shipping_address.country |
string | 否 | 配送地址所在国家的 ISO 代码。 |
以下是一些示例:
# 示例 1: 创建一个包含账单地址和配送地址的客户对象。
customer = {
"billing_address": {
"first_name": "名",
"last_name": "姓氏",
"address_1": "地址",
"address_2": "",
"city": "城市",
"state": "州",
"postcode": "邮政编码",
"country": "国家",
"email": "邮件",
"phone": "电话号码"
},
"shipping_address": {
"first_name": "名",
"last_name": "姓氏",
"address_1": "地址",
"address_2": "",
"city": "城市",
"state": "州",
"postcode": "邮政编码",
"country": "国家"
}
}
# 示例 2: 设置一个客户的属性。
set_customer_attribute(customer, "description", "描述")
# 示例 3: 获取一个数值。
number = get_number()
# 示例 4: 循环 %d 秒。
for i in range(1, %d):
print("一 %s 秒" % "second")
# 示例 5: 检查一个条件。
if no:
print("否")
else:
print("是")
# 示例 6: 使用 Code
请注意,String 是一个 String 类型。 Phone Number 必须是有效的 Phone Number。 First name 不能为空。 Attribute 必须是有效的 Attribute。 Last Name 不能为空。 Shipping 必须是有效的 Shipping 地址。 Address 必须是有效的 Address。 Second 表示 Second。 number 表示 number。 Code 表示 Code。 Mail 表示 Mail。 Red 表示 Red。 one 表示 one。 For 表示 For。 In 表示 In。 No 表示 No。 Shipping Address 表示 Shipping Address。 Description 表示 Description。 Customer 表示 Customer。
返回全部的 购物车回复,如果成功;否则,返回一个 错误回复。
选择配送费率
选择一个可用的配送费率,然后返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此接口将返回一个错误。
POST /cart/select-shipping-rate
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
package_id |
integer | 是 | 购物车中配送包的 ID。 |
rate_id |
string | 是 | 选定的配送包的费率 ID。 |
curl --header "Nonce: 12345" --request POST /cart/select-shipping-rate?package_id=1&rate_id=flat_rate:1
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
结账订单 API
结账订单 API 旨在简化现有订单的处理和付款操作。
所有结账订单接口都需要一个 随机数 Token 或一个 购物车 Token,否则这些接口将返回一个错误。
处理订单和支付
接受最终选择的支付方法,以及任何额外的支付数据,然后尝试支付并返回结果。
POST /wc/store/v1/checkout/{ORDER_ID}
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 用于订单验证的密钥。 |
billing_email |
字符串 | 否 | 用于验证访客订单的 Email 地址。 |
billing_address |
对象 | 是 | 客户已更新的账单地址数据对象。 |
shipping_address |
对象 | 是 | 客户已更新的配送地址数据对象。 |
payment_method |
字符串 | 是 | 用于处理支付的支付方法 ID。 |
payment_data |
数组 | 否 | 在处理支付时传递给支付方法的数据。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/checkout/{ORDER_ID} -d '{"key":"wc_order_oFmQYREzh9Tfv","billing_email":"admin@example.com","payment_method":"cheque","billing_address":{...},"shipping_address":{...}'
示例请求:
{
"key": "wc_order_oFmQYREzh9Tfv",
"billing_email": "admin@example.com",
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"payment_method": "cheque",
"payment_data": []
}
示例响应:
# 订单详情
以下是订单的详细信息。
**订单 ID:** %d
**状态:** %s
## 订单概览
* **订单 ID:** %d
* **状态:** %s
* **订单 Key:** %s
* **客户备注:** %s
* **客户 ID:** %d
## 账单地址
* **地址:**
* **姓名:** %s
* **公司:** %s
* **地址 1:** %s
* **地址 2:** %s
* **城市:** %s
* **州/省:** %s
* **邮编:** %s
* **国家:** %s
* **邮箱:** %s
* **电话:** %s
## 配送地址
* **地址:**
* **姓名:** %s
* **公司:** %s
* **地址 1:** %s
* **地址 2:** %s
* **城市:** %s
* **州/省:** %s
* **邮编:** %s
* **国家:** %s
* **电话:** %s
## 支付信息
* **支付方法:** %s
* **支付结果:**
* **支付状态:** %s
* **支付详情:** %s
* **重定向 URL:** %s
## 订单管理
* **管理员:** 只有管理员才能查看和修改订单信息。
* **检查:** 定期检查订单状态,确保顺利完成。
* **锁定:** 在处理订单时,可以锁定订单以防止其他用户修改。
* **邮件:** 系统会发送邮件通知客户订单状态更新。
* **新增:** 管理员可以新增订单。
* **红色:** 某些情况下,订单状态会显示为红色,表示存在问题。
* **网址:** 请注意以下网址。
* **关键字:** 使用关键字进行订单搜索。
```json
{
"order_id": 146,
"status": "on-hold",
"order_key": "wc_order_oFmQYREzh9Tfv",
"customer_note": "",
"customer_id": 1,
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"payment_method": "cheque",
"payment_result": {
"payment_status": "success",
"payment_details": [],
"redirect_url": "https://local.wordpress.test/block-checkout/order-received/146/?key=wc_order_VPffqyvgWVqWL"
}
}
常见问题
- 如何修改订单信息? 只有管理员可以修改订单信息。
- 如何取消订单? 请联系客服进行取消。
- 如何查看订单状态? 您可以在账户中查看订单状态。
- 如何进行退货? 请参考我们的退货政策。
- 配送时间是多久? 配送时间取决于您的地址和选择的配送方式。
- 结账时遇到了问题,怎么办? 请联系客服寻求帮助。
- 如何联系客服? 您可以通过邮件或电话联系客服。
- 测试环境: 这是测试环境,所有数据均为测试数据。
## 支付数据
有很多支付网关可供商家使用,并且每个网关都期望接收不同的 `payment_data`。 我们无法全面列出所有支付网关期望的所有请求,因此我们建议您联系您正在使用的支付网关插件的作者,以获取更多信息。
以下是一个使用 [WooCommerce Stripe 支付网关](https://wordpress.org/plugins/woocommerce-gateway-stripe/) 时,发送到结账订单端点的支付数据的示例。
有关生成 `stripe_source` 的更多信息,请查看 [Stripe 文档](https://stripe.com/docs)。
```json
{
"payment_data": [
{
"key": "stripe_source",
"value": "src_xxxxxxxxxxxxx"
},
{
"key": "billing_email",
"value": "myemail@email.com"
},
{
"key": "billing_first_name",
"value": "Jane"
},
{
"key": "billing_last_name",
"value": "Doe"
},
{
"key": "paymentMethod",
"value": "stripe"
},
{
"key": "paymentRequestType",
"value": "cc"
},
{
"key": "wc-stripe-new-payment-method",
"value": true
}
]
}
结账 API
结账 API 允许创建订单(基于当前的购物车)并处理付款方式的支付。
所有结账端点都需要一个 Nonce Token 或一个 Cart Token,否则这些端点将返回一个错误。
获取结账数据
返回用于结账所需的数据。 这包括一个草稿订单(基于当前的购物车)以及客户的账单和配送地址。 支付信息将为空,因为它只有在通过 POST 请求更新订单时才会持久化(在支付处理之前)。
GET /wc/store/v1/checkout
此端点不需要任何参数。
curl --header "Nonce: 12345" --request GET https://example-store.com/wp-json/wc/store/v1/checkout
示例响应
{
"order_id": 146,
"status": "checkout-draft",
"order_key": "wc_order_VPffqyvgWVqWL",
"customer_note": "",
"customer_id": 1,
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US"
},
"payment_method": "",
"payment_result": {
"payment_status": "",
"payment_details": [],
"redirect_url": ""
}
}
更新结账数据
此接口允许您更新当前订单的结账数据。例如,这可以从前端调用以持久化结账字段。
PUT /wc/store/v1/checkout?__experimental_calc_totals=true
请注意 __experimental_calc_totals 参数。 此参数用于确定是否应重新计算购物车总额。 如果购物车总额是响应 PUT 请求而更新的,则应将其设置为 true,否则设置为 false。
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
additional_fields |
object | 否 | 要更新的其他字段的名称 => 值对。 |
payment_method |
string | 否 | 选定的支付方式的 ID。 |
order_notes |
string | 否 | 订单备注。 |
curl --header "Nonce: 12345" --request PUT https://example-store.com/wp-json/wc/store/v1/checkout?additional_fields[plugin-namespace/leave-on-porch]=true&additional_fields[plugin-namespace/location-on-porch]=dsdd&payment_method=bacs&order_notes=Please%20leave%20package%20on%20back%20porch
示例请求
{
"additional_fields": {
"plugin-namespace/leave-on-porch": true,
"plugin-namespace/location-on-porch": "dsdd"
},
"payment_method": "bacs",
"order_notes": "Please leave package on back porch"
}
示例响应
{
"order_id": 1486,
"status": "checkout-draft",
"order_key": "wc_order_KLpMaJ054PVlb",
"order_number": "1486",
"customer_note": "",
"customer_id": 1,
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US"
},
"payment_method": "bacs",
"payment_result": null,
"additional_fields": {
"plugin-namespace/leave-on-porch": true,
"plugin-namespace/location-on-porch": "dsdd"
},
"__experimentalCart": { ... },
"extensions": {}
}
请注意响应中返回的 __experimentalCart 字段。 在 PUT 请求之后,总额将在前端更新。 这使得可以响应通过 PUT 请求持久化的字段来操纵购物车总额。
处理订单和支付
接受最终的客户地址和选择的支付方法,以及任何额外的支付数据,然后尝试支付并返回结果。
POST /wc/store/v1/checkout
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
billing_address |
object | 是 | 客户更新后的账单地址数据对象。 |
shipping_address |
object | 是 | 客户更新后的配送地址数据对象。 |
customer_note |
string | 否 | 客户在结账过程中添加到订单的备注。 |
payment_method |
string | 是 | 用于处理支付的支付方法 ID。 |
payment_data |
array | 否 | 在处理支付时传递给支付方法的的数据。 |
customer_password |
string | 否 | 可选地,为新帐户定义密码。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/checkout?payment_method=paypal&payment_data[0][key]=test-key&payment_data[0][value]=test-value
示例请求
{
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US"
},
"customer_note": "Test notes on order.",
"create_account": false,
"payment_method": "cheque",
"payment_data": [],
"extensions": {
"some-extension-name": {
"some-data-key": "some data value"
}
}
}
支付数据
有很多支付网关可供商家使用,并且每个网关都期望接收不同的 payment_data。 我们无法全面列出所有支付网关期望的请求,因此我们建议您联系您正在使用的支付网关插件的作者,以获取更多信息。
以下是一个使用 WooCommerce Stripe 支付网关 时,发送到结账端点的支付数据的示例。
有关如何生成 stripe_source 的更多信息,请查阅 Stripe 文档。
{
"payment_data": [
{
"key": "stripe_source",
"value": "src_xxxxxxxxxxxxx"
},
{
"key": "billing_email",
"value": "myemail@email.com"
},
{
"key": "billing_first_name",
"value": "Jane"
},
{
"key": "billing_last_name",
"value": "Doe"
},
{
"key": "paymentMethod",
"value": "stripe"
},
{
"key": "paymentRequestType",
"value": "cc"
},
{
"key": "wc-stripe-new-payment-method",
"value": true
}
]
}
订单 API
订单 API 返回用于支付订单的信息。
获取订单
GET /order/{ORDER_ID}?key={KEY}&billing_email={BILLING_EMAIL}
此接口有一个必需的参数,即 key。 对于访客订单,必须添加 billing_email。
curl "https://example-store.com/wp-json/wc/store/v1/order/{ORDER_ID}?key={KEY}&billing_email={BILLING_EMAIL}"
返回完整的订单对象回复(参见 订单回复)。
回复
订单接口返回的回复格式与 /cart 相同;它是一个订单对象,包含订单项目、已应用的优惠券、配送地址和费率,以及非敏感的客户数据。
订单回复
本节描述了系统对订单的回复。
响应格式
回复采用以下 JSON 格式:
{
"status": "success" | "failed",
"order_id": "%s",
"message": "操作成功" | "订单不存在" | "支付失败" | "其他错误信息"
}
status: 表示操作的成功或失败。order_id: 订单的唯一标识符。message: 包含操作结果的详细信息。
成功回复 (status: success)
当订单处理成功时,系统会返回以下回复:
{
"status": "success",
"order_id": "%s",
"message": "操作成功"
}
失败回复 (status: failed)
当订单处理失败时,系统会返回以下回复:
{
"status": "failed",
"order_id": "%s",
"message": "订单不存在" | "支付失败" | "其他错误信息"
}
错误处理
如果出现错误,系统会返回 status: failed 的回复,并包含详细的错误信息。 例如,如果订单不存在,系统会返回:
{
"status": "failed",
"order_id": "%s",
"message": "订单不存在"
}
API 使用示例
以下是一个使用 getOrderResponse 函数的示例:
def getOrderResponse(order_id):
"""
获取订单的回复。
Args:
order_id: 订单的 ID。
Returns:
一个包含回复信息的字典。
"""
# ... (省略实现细节) ...
return {
"status": "success",
"order_id": order_id,
"message": "操作成功"
}
其他说明
getOrderResponse函数可能返回不同的message值,具体取决于订单的状态。- 如果
order_id无效,getOrderResponse函数会返回status: failed的回复。 - 系统会记录所有订单操作,包括成功和失败的回复。
%s是一个占位符,表示要插入的字符串值。{name}是一个占位符,表示要插入的变量名。Or表示“或”。on表示“开”。Response表示“回复”。
{
"id": 147,
"status": "待审",
"coupons": [
{
"code": "discount20",
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"total_discount": "421",
"total_discount_tax": "0"
}
}
],
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"items": [
{
"key": "9bf31c7ff062936a96d3c8bd1f8f2ff3",
"id": 15,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 99,
"multiple_of": 1,
"editable": true
},
"name": "Beanie",
"short_description": "<p>This is a simple product.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-beanie",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/beanie/",
"images": [
{
"id": 44,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2.jpg 801w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "beanie-2.jpg",
"alt": ""
}
],
"variation": [],
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1000",
"regular_price": "2000",
"sale_price": "1000",
"price_range": null,
"raw_prices": {
"precision": 6,
"price": "10000000",
"regular_price": "20000000",
"sale_price": "10000000"
}
},
"item_data": [],
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"line_subtotal": "1000",
"line_subtotal_tax": "0",
"line_total": "800",
"line_total_tax": "0"
},
"catalog_visibility": "view"
},
{
"key": "e369853df766fa44e1ed0ff613f563bd",
"id": 34,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 99,
"multiple_of": 1,
"editable": true
},
"name": "WordPress Pennant",
"short_description": "<p>This is an 外部产品.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "wp-pennant",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/wordpress-pennant/",
"images": [
{
"id": 57,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "pennant-1.jpg",
"alt": ""
}
],
"variation": [],
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1105",
"regular_price": "1105",
"sale_price": "1105",
"price_range": null,
"raw_prices": {
"precision": 6,
"price": "11050000",
"regular_price": "11050000",
"sale_price": "11050000"
}
},
"item_data": [],
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"line_subtotal": "1105",
"line_subtotal_tax": "0",
"line_total": "884",
"line_total_tax": "0"
},
"catalog_visibility": "view"
}
],
"needs_payment": true,
"needs_shipping": true,
"totals": {
"subtotal":"2105",
"total_discount": "421",
"total_shipping": "500",
"total_fees": "0",
"total_tax": "0",
"total_refund": "0",
"total_price": "2184",
"total_items": "2105",
"total_items_tax": "0",
"total_fees_tax": "0",
"total_discount_tax": "0",
"total_shipping_tax": "0",
"tax_lines": []
},
"errors": [],
"payment_requirements": [ "products" ],
}
错误回复
如果无法执行某个订单操作,将会返回一个错误回复。该回复将包含一个原因代码和一个错误信息:
{
"code": "woocommerce_rest_invalid_order",
"message": "提供的订单 ID 或关键字无效。",
"data": {
"status": 401
}
}
产品 属性 术语 API
GET /products/attributes/:id/terms
GET /products/attributes/:id/terms?orderby=slug
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer | 是 | 要获取术语的属性的 ID。 |
order |
string | 否 | 升序或降序排序。 允许的值:asc, desc |
orderby |
string | 否 | 按对象属性排序集合。 允许的值:id, name, name_num, slug, count, menu_order. |
curl "https://example-store.com/wp-json/wc/store/v1/products/attributes/1/terms"
示例响应:
[
{
"id": 22,
"name": "Blue",
"slug": "blue",
"count": 5
},
{
"id": 48,
"name": "Burgundy",
"slug": "burgundy",
"count": 1
}
]
产品属性 API
获取产品属性列表
GET /products/attributes
此接口不需要任何参数。
curl "https://example-store.com/wp-json/wc/store/v1/products/attributes"
示例响应:
[
{
"id": 1,
"name": "Color",
"taxonomy": "pa_color",
"type": "select",
"order": "menu_order",
"has_archives": false
},
{
"id": 2,
"name": "Size",
"taxonomy": "pa_size",
"type": "select",
"order": "menu_order",
"has_archives": false
}
]
获取单个产品属性
获取单个属性分类法。
GET /products/attributes/:id
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer | 是 | 要检索的属性的 ID。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/attributes/1"
示例响应:
{
"id": 1,
"name": "Color",
"taxonomy": "pa_color",
"type": "select",
"order": "menu_order",
"has_archives": false
}
产品品牌 API
本 API 提供了访问产品品牌信息的接口。
功能描述:
该 API 允许您:
- 查询所有可用的品牌。
- 根据品牌 ID 获取特定品牌的详细信息。
- 根据品牌名称进行模糊搜索。
API 端点:
GET /api/v1/brands: 获取所有品牌。GET /api/v1/brands/{brand_id}: 获取指定 ID 的品牌。
请求参数:
| 参数名 | 类型 | 描述 | 是否必选 |
|---|---|---|---|
brand_id |
int |
品牌 ID。仅在 GET /api/v1/brands/{brand_id} 中使用。 |
否 |
query |
string |
搜索关键词。仅在 GET /api/v1/brands 中使用。 |
否 |
响应格式:
响应以 JSON 格式返回。
示例:
-
获取所有品牌:
GET /api/v1/brands响应:
[ { "id": 1, "name": "Brand A", "description": "Description for Brand A" }, { "id": 2, "name": "Brand B", "description": "Description for Brand B" } ] -
获取指定 ID 的品牌:
GET /api/v1/brands/1响应:
{ "id": 1, "name": "Brand A", "description": "Description for Brand A" } -
根据品牌名称进行模糊搜索:
GET /api/v1/brands?query=Brand%20A响应:
[ { "id": 1, "name": "Brand A", "description": "Description for Brand A" } ]
错误处理:
API 使用标准的 HTTP 状态码来指示操作的成功或失败。
200 OK: 请求成功。400 Bad Request: 请求参数无效。404 Not Found: 资源未找到。500 Internal Server Error: 服务器内部错误。
版本:
v1.0
注意事项:
- 本 API 仅适用于 %s 产品。
- 请勿滥用 API,否则可能被限制访问。
- 对于 Pro 版本,请联系您的管理员获取 API 密钥。
- 更多信息,请访问 https://example.com/api-documentation。
- 如果遇到问题,请联系我们的技术支持团队:support@example.com。
- 本 API 遵循 RESTful 架构风格。
{name}是一个占位符,表示用户的姓名。%d是一个整数占位符。%s是一个字符串占位符。- 本 API 支持多种数据格式,包括 JSON 和 XML。
- 本 API 提供了详细的日志记录功能,方便问题排查。
- 本 API 具有高可用性和可扩展性。
- 本 API 提供了完善的安全性机制,保护您的数据安全。
- 本 API 持续更新和改进,以满足您的需求。
- 本 API 的使用需要遵守我们的服务条款。
- 本 API 提供了多种认证方式,包括 API 密钥和 OAuth 2.0。
- 本 API 提供了详细的文档和示例代码,方便您快速上手。
- 本 API 团队致力于为您提供优质的技术支持。
- 本 API 遵循最佳实践,确保代码质量和可维护性。
- 本 API 具有良好的性能和响应速度。
- 本 API 提供了多种监控指标,方便您了解 API 的运行状态。
- 本 API 具有强大的错误处理能力,能够快速恢复。
- 本 API 遵循开放标准,方便与其他系统集成。
- 本 API 具有良好的兼容性,支持多种操作系统和编程语言。
- 本 API 提供了多种部署选项,包括云端和本地部署。
- 本 API 具有良好的可扩展性,能够满足您的业务增长
列出产品品牌
GET /products/brands
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
context |
字符串 | 否 | 发送请求的范围;决定响应中包含的字段。 |
page |
整数 | 否 | 集合的当前页。默认为 1。 |
per_page |
整数 | 否 | 结果集中返回的最大项目数。默认为无限制。允许的值在 0 和 100 之间。 |
search |
字符串 | 否 | 限制结果,仅包含匹配的字符串。 |
exclude |
数组 | 否 | 确保结果集排除特定的 ID。 |
include |
数组 | 否 | 限制结果集为特定的 ID。 |
order |
字符串 | 否 | 升序或降序排序。允许的值:asc, desc。默认为 asc。 |
orderby |
字符串 | 否 | 按属性排序。允许的值:name, slug, count。默认为 name。 |
hide_empty |
布尔值 | 否 | 如果为 true,则不返回空项。默认为 true。 |
parent |
整数 | 否 | 限制结果,仅包含具有特定父级 ID 的项。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/brands"
示例响应:
[
{
"id": 16,
"name": "Nike",
"slug": "nike",
"description": "This is the Nike brand.",
"parent": 0,
"count": 11,
"image": {
"id": 55,
"src": "https://store.local/wp-content/uploads/2021/11/nike-logo.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/nike-logo-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/nike-logo.jpg 800w, https://store.local/wp-content/uploads/2021/11/nike-logo-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/nike-logo-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/nike-logo-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/nike-logo-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/nike-logo-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/nike-logo-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "nike-logo.jpg",
"alt": ""
},
"review_count": 2,
"permalink": "https://store.local/product-brand/nike/"
},
{
"id": 21,
"name": "Adidas",
"slug": "adidas",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-brand/adidas/"
}
]
产品品牌列表
以下是产品品牌的列表。每个品牌都有一个名称、别名、描述、父级、计数、图像、评价计数和固定链接。
品牌信息
- 名称 (Name): 品牌名称。
- 别名 (Slug): 品牌的别名,用于生成 URL。
- 描述 (Description): 品牌的详细描述。
- 父级 (Parent): 父级品牌的 ID。如果品牌是顶级品牌,则为 0。
- 计数 (Count): 品牌下的产品数量。
- 图像 (Image): 品牌的图像信息,包括 ID、源地址、缩略图地址、srcset、sizes、名称和 alt 文本。
- 评价计数 (Review Count): 品牌的评价数量。
- 固定链接 (Permalink): 品牌的固定链接地址。
示例
以下是两个产品品牌的示例:
-
Nike:
- 名称: Nike
- 别名: nike
- 描述: This is the Nike brand.
- 父级: 0
- 计数: 11
- 图像: 包含图像的详细信息。
- 评价计数: 2
- 固定链接: https://store.local/product-brand/nike/
-
Adidas:
- 名称: Adidas
- 别名: adidas
- 描述:
- 父级: 0
- 计数: 1
- 图像: null
- 评价计数: 1
- 固定链接: https://store.local/product-brand/adidas/
上传图像
您可以通过以下步骤上传图像:
- 点击“上传”按钮。
- 选择要上传的图像文件。
- 填写图像的标题、描述和 alt 文本。
- 点击“插入到内容”按钮。
调整图像大小
您可以通过以下方法调整图像大小:
- 使用图像编辑软件调整图像大小。
- 在 WordPress 中使用图像编辑插件调整图像大小。
更多信息
有关更多信息,请查看 WordPress 文档或联系技术支持。
您可以在本地服务器上查看日志文件,以获取更多信息。
请注意,Width 属性表示图像的宽度。Brand 属性表示品牌。Store 属性表示商店。Log 属性表示日志。In 预示着某个位置。and 连接两个词语。View 动作表示查看。
单个品牌
获取单个品牌信息。
GET /products/brands/:id
或者
GET /products/brands/:slug
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
identifier |
字符串 | 是 | 用于获取品牌的标识符。可以是品牌 ID 或别名。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/brands/1"
或者
curl "https://example-store.com/wp-json/wc/store/v1/products/brands/adidas"
示例回复:
{
"id": 1,
"name": "Adidas",
"slug": "adidas",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-brand/adidas/"
}
产品类别 API
本 API 允许您访问和管理产品类别信息。
目录
- 获取所有产品类别
- 按 ID 获取产品类别
- 创建产品类别
- 更新产品类别
- 删除产品类别
获取所有产品类别
此 API 端点允许您获取所有可用的产品类别。
请求方法: GET
请求 URL: /api/v1/product_categories
响应:
[
{
"id": 1,
"name": "Electronics",
"description": "Electronic devices and accessories"
},
{
"id": 2,
"name": "Clothing",
"description": "Apparel and fashion items"
}
]
按 ID 获取产品类别
此 API 端点允许您通过 ID 获取特定产品类别的信息。
请求方法: GET
请求 URL: /api/v1/product_categories/{id}
参数:
id: 要获取的产品类别的 ID。
响应:
{
"id": 1,
"name": "Electronics",
"description": "Electronic devices and accessories"
}
创建产品类别
此 API 端点允许您创建新的产品类别。
请求方法: POST
请求 URL: /api/v1/product_categories
请求体:
{
"name": "New Category",
"description": "Description of the new category"
}
响应:
{
"id": 3,
"name": "New Category",
"description": "Description of the new category"
}
更新产品类别
此 API 端点允许您更新现有产品类别的属性。
请求方法: PUT
请求 URL: /api/v1/product_categories/{id}
参数:
id: 要更新的产品类别的 ID。
请求体:
{
"name": "Updated Category Name",
"description": "Updated description of the category"
}
响应:
{
"id": 1,
"name": "Updated Category Name",
"description": "Updated description of the category"
}
删除产品类别
此 API 端点允许您删除现有产品类别。
请求方法: DELETE
请求 URL: /api/v1/product_categories/{id}
参数:
id: 要删除的产品类别的 ID。
响应:
成功删除时,返回状态码 204 No Content。
错误处理:
如果发生错误,API 将返回相应的错误代码和消息。例如,如果尝试访问不存在的产品类别,则返回 404 Not Found。
示例:
使用 curl 命令获取所有产品类别:
curl -X GET http://example.com/api/v1/product_categories
使用 curl 命令创建新的产品类别:
curl -X POST -H "Content-Type: application/json" -d '{"name": "New Category", "description": "Description of the new category"}' http://example.com/api/v1/product_categories
注意:
- 所有 API 请求都需要有效的 API 密钥。
Pro版本提供额外的功能和更高的速率限制。Category字段表示产品所属的分类。Or表示“或”。at表示“在”。Go表示“提交”。- 请参考 API 文档以获取更多详细信息。
- 有关 API 使用的更多信息,请访问 API Documentation.
- 您可以在 %s 处找到更多信息。
- 请使用 %d 作为 ID。
- 您的姓名是 {name}。
列出产品分类
GET /products/categories
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
context |
字符串 | 否 | 发送请求的范围;决定响应中包含的字段。 |
page |
整数 | 否 | 集合的当前页。默认为 1。 |
per_page |
整数 | 否 | 结果集中返回的最大项目数。默认为无限制。允许的值在 0 和 100 之间。 |
search |
字符串 | 否 | 限制结果,仅包含与字符串匹配的结果。 |
exclude |
数组 | 否 | 确保结果集排除特定的 ID。 |
include |
数组 | 否 | 限制结果集为特定的 ID。 |
order |
字符串 | 否 | 升序或降序排序。允许的值:asc, desc。默认为 asc。 |
orderby |
字符串 | 否 | 按属性排序。允许的值:name, slug, count。默认为 name。 |
hide_empty |
布尔值 | 否 | 如果为 true,则不返回空项。默认为 true。 |
parent |
整数 | 否 | 限制结果,仅包含具有特定父级 ID 的项。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/categories"
示例响应:
[
{
"id": 16,
"name": "Clothing",
"slug": "clothing",
"description": "This is the clothing category.",
"parent": 0,
"count": 11,
"image": {
"id": 55,
"src": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1.jpg 800w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "t-shirt-with-logo-1.jpg",
"alt": ""
},
"review_count": 2,
"permalink": "https://store.local/product-category/clothing/"
},
{
"id": 21,
"name": "Decor",
"slug": "decor",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-category/decor/"
}
]
产品分类
本页面展示了商店中的产品分类。
分类列表
以下是可用的分类列表:
- Clothing: 服装分类。
Description: This is the clothing category.Permalink: https://store.local/product-category/clothing/ - Decor: 装饰品分类。
Description: .Permalink: https://store.local/product-category/decor/
分类详情
点击分类名称可以查看该分类下的所有产品。每个分类都有一个别名,用于URL链接。
分类属性
id: 分类ID。name: 分类名称。slug: 分类别名。description: 分类描述。parent:父级分类ID。count:计数,表示该分类下的产品数量。image: 分类图像信息。id:图像ID。src:图像原始链接。thumbnail:图像缩略图链接。srcset:图像不同尺寸的链接集合。sizes:图像尺寸属性。name:图像文件名。alt:图像替代文本。
review_count:评价数量。permalink:固定链接。
上传
您可以在此处上传新的图像或文件。
日志
日志文件记录了系统操作。
商店设置
您可以在此处配置商店的各种设置。
宽度和尺寸
宽度和尺寸是图像的重要属性。
链接
链接到其他页面或资源。
内容
内容是网页的主要部分。
在线
在线状态。
本地
本地文件。
评论
评论是对产品或内容的反馈。
类别
分类用于组织内容。
别名
别名是名称的另一种形式,通常用于URL。
产品
产品是商店中的可售商品。
视图
查看页面或内容。
尺寸
尺寸是图像或产品的属性。
产品分类
获取单个分类。
GET /products/categories/:id
| 分类 | 类型 | 必填 | 描述 |
|---|---|---|---|
id |
整数 | 是 | 要检索的分类的 ID。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/categories/1"
示例回复:
{
"id": 1,
"name": "Decor",
"slug": "decor",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-category/decor/"
}
产品集合数据 API
此接口允许您获取产品集合的聚合数据,例如,在一个产品集合中获取最高和最低价格(忽略分页)。 这由产品筛选小工具中的块使用,因为计数基于正在查看的产品目录。
GET /products/collection-data
GET /products/collection-data?calculate_price_range=true
GET /products/collection-data?calculate_attribute_counts[0][query_type]=or&calculate_attribute_counts[0][taxonomy]=pa_color
GET /products/collection-data?calculate_rating_counts=true
GET /products/collection-data?calculate_taxonomy_counts=product_cat
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
calculate_price_range |
bool | 否 | 返回产品集合的最低和最高价格。 如果为 false,则仅返回 null。 |
calculate_attribute_counts |
object | 否 | 返回一组属性分类的属性计数,您可以通过此参数传递这些分类。 每个分类应以包含键 "taxonomy" 和 "query_type" 的对象形式提供。 如果为空,则返回 null。 |
calculate_rating_counts |
bool | 否 | 返回具有特定平均评级的产品的计数,范围为 1-5。 如果为 false,则仅返回 null。 |
calculate_stock_status_counts |
bool | 否 | 返回具有每种库存状态(在库存中、缺货、延期交货)的产品计数。 如果为 false,则仅返回 null。 |
calculate_taxonomy_counts |
array | 否 | 返回一组分类的分类计数,您可以通过此参数传递这些分类。 每个分类应以分类名称字符串的形式提供。 如果为空,则返回 null。 |
除了上述属性之外,还支持所有产品列表属性。 这允许您获取特定产品子集的数据。 请参阅 产品 API 列表产品部分,以获取完整列表。
curl "https://example-store.com/wp-json/wc/store/v1/products/collection-data?calculate_price_range=true&calculate_attribute_counts=pa_size,pa_color&calculate_rating_counts=true&calculate_taxonomy_counts=product_cat,product_tag"
{
"price_range": [
"currency_minor_unit": 2,
"min_price": "0",
"max_price": "9000",
"currency_code": "USD",
"currency_decimal_separator": ".",
"currency_minor_unit": 2,
"currency_prefix": "$",
"currency_suffix": "",
"currency_symbol": "$",
"currency_thousand_separator": ",",
],
"attribute_counts": [
{
"term": 22,
"count": 4
},
{
"term": 23,
"count": 3
},
{
"term": 24,
"count": 4
}
],
"rating_counts": [
{
"rating": 3,
"count": 1
},
{
"rating": 4,
"count": 1
}
],
"taxonomy_counts": [
{
"term": 25,
"count": 8
},
{
"term": 26,
"count": 6
},
{
"term": 27,
"count": 2
}
]
}
产品评论 API
本 API 提供了访问产品评论数据的接口。
功能描述:
该 API 允许您:
- 获取产品评论: 您可以根据产品 ID 获取相关的评论列表。
- 过滤评论: 您可以根据不同的条件(例如,评分、日期)过滤评论。
- 查看评论详情: 您可以查看单个评论的详细信息。
API 端点:
GET /api/v1/products/{product_id}/reviews:获取指定产品 ID 的所有评论。
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
product_id |
int |
是 | 产品 ID |
page |
int |
否 | 页码,默认为 1 |
page_size |
int |
否 | 每页显示的数量,默认为 20 |
sort_by |
string |
否 | 排序字段,例如 rating, date |
sort_order |
string |
否 | 排序方式,asc (升序) 或 desc (降序) |
响应格式:
{
"total_count": %d,
"page": %d,
"page_size": %d,
"reviews": [
{
"id": %d,
"product_id": %d,
"user": {
"name": "%s",
"email": "%s"
},
"rating": %d,
"comment": "%s",
"date": "%s"
}
]
}
示例请求:
GET /api/v1/products/123/reviews?page=2&page_size=10&sort_by=rating&sort_order=desc
错误处理:
| 状态码 | 描述 |
|---|---|
| 400 | 错误的请求参数。 |
| 404 | 未找到指定的产品或评论。 |
| 500 | 服务器内部错误。 |
版本:
v1.0
注意事项:
- 请确保您已获得访问 API 的权限。
- API 使用速率限制,请遵守相关规定。
Pro版本提供更高级的功能和更高的速率限制。
其他:
- 您可以在 这里 找到更详细的文档。
- 如果您有任何问题,请联系我们的技术支持团队。
View更多信息。
获取产品评论
此接口返回产品评论,并且可以显示特定产品或特定分类的结果。
GET /products/reviews
GET /products/reviews?category_id=1,2,3
GET /products/reviews?product_id=1,2,3
GET /products/reviews?orderby=rating&order=desc
| 属性 | 类型 | 是否必选 | 描述 |
|---|---|---|---|
page |
integer | 否 | 集合的当前页。 |
per_page |
integer | 否 | 结果集中返回的最大项目数。 |
offset |
integer | 否 | 通过指定数量的项目偏移结果集。 |
order |
string | 否 | 按照升序或降序排序属性。 允许的值:asc, desc |
orderby |
string | 否 | 按照对象属性对集合进行排序。 允许的值:date, date_gmt, id, rating, product |
category_id |
string | 否 | 将结果集限制为来自特定分类 ID 的评论。 |
product_id |
string | 否 | 将结果集限制为来自特定产品 ID 的评论。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/collection-data?calculate_price_range=true&calculate_attribute_counts=pa_size,pa_color&calculate_rating_counts=true"
示例响应:
[
{
"id": 83,
"date_created": "2022-01-12T15:42:14",
"formatted_date_created": "一月 12, 2022",
"date_created_gmt": "2022-01-12T15:42:14",
"product_id": 33,
"product_name": "带有Logo的帽子",
"product_permalink": "https://store.local/product/beanie-with-logo/",
"product_image": {
"id": 56,
"src": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1.jpg 800w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "beanie-with-logo-1.jpg",
"alt": ""
},
"reviewer": "reviewer-name",
"review": "<p>这是一个非常棒的产品。</p>\n",
"rating": 5,
"verified": true,
"reviewer_avatar_urls": {
"24": "https://secure.gravatar.com/avatar/12345?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/12345?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/12345?s=96&d=mm&r=g"
}
}
]
产品信息
本页面展示了产品信息。
字段说明
id: 产品IDdate_created: 创建日期formatted_date_created: 格式化的创建日期product_id: 产品IDproduct_name: 产品名称product_permalink: 固定链接product_image: 产品图片信息src: 图片网址thumbnail: 缩略图网址srcset: 图片集合sizes: 图片尺寸name: 图片名称alt: 图片描述
reviewer: 评价者review: 评价内容rating: 评分verified: 是否为已验证的评价reviewer_avatar_urls: 评价者头像网址
示例
以下是一个产品评价的示例:
[
{
"id": 83,
"date_created": "2022-01-12T15:42:14",
"formatted_date_created": "January 12, 2022",
"product_id": 33,
"product_name": "Beanie with Logo",
"product_permalink": "https://store.local/product/beanie-with-logo/",
"product_image": { ... },
"reviewer": "reviewer-name",
"review": "<p>This is a fantastic product.</p>\n",
"rating": 5,
"verified": true,
"reviewer_avatar_urls": { ... }
}
]
详细信息
date_created: 表示产品创建的日期和时间。product_name: 产品的名称。product_permalink: 指向产品详情页面的固定链接。product_image: 包含产品图片的各种尺寸和格式的信息。review: 用户对产品的评价内容。rating: 用户对产品的评分,通常是 1 到 5 之间的数字。verified: 指示该评价是否已通过验证。
上传文件
您可以通过点击“上传”按钮来上传文件。上传完成后,您可以设置文件的标题、描述和固定链接。
创建新产品
要创建新产品,请点击“创建”按钮。您需要填写产品名称、描述、价格、图片等信息。
商店设置
在商店设置中,您可以配置商店的名称、地址、联系方式、支付方式、运费规则等。
日志
Log文件记录了系统的运行状态和错误信息。
宽度
Width参数用于设置图像的宽度。
头像
Avatar是用户在论坛或社交媒体上使用的个人图像。
格式
Format是指文件或数据的格式,例如文本格式、图像格式等。
链接
Link是指网页之间的连接。
内容
Content是指文章或网页的文本和媒体。
评分
Rating是指用户对产品或服务的评价。
评价
Review是指用户对产品或服务的详细评价。
为
For表示为了。
在
In表示在...里面。
产品
Product是指商店中销售的商品。
日期
Date是指年月日。
增值税
VAT是指增值税。
已创建
Created表示已经创建。
网址
Url是指网址。
产品标签 API
列出产品标签
GET /products/tags
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
context |
字符串 | 否 | 发送请求的范围;决定响应中包含的字段。 |
page |
整数 | 否 | 集合的当前页。默认为 1。 |
per_page |
整数 | 否 | 结果集中返回的最大项目数。默认为无限制。允许的值在 0 和 100 之间。 |
search |
字符串 | 否 | 限制结果,仅包含匹配的字符串。 |
exclude |
数组 | 否 | 确保结果集排除特定的 ID。 |
include |
数组 | 否 | 限制结果集为特定的 ID。 |
order |
字符串 | 否 | 升序或降序排序。允许的值:asc, desc。默认为 asc。 |
orderby |
字符串 | 否 | 按属性排序。允许的值:name, slug, count。默认为 name。 |
hide_empty |
布尔值 | 否 | 如果为 true,则不返回空项。默认为 true。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/tags"
示例响应:
[
{
"id": 1,
"name": "Test Tag",
"slug": "test-tag",
"description": "",
"parent": 0,
"count": 1
},
{
"id": 2,
"name": "Another Tag",
"slug": "another-tag",
"description": "",
"parent": 0,
"count": 1
}
]
产品 API
该商店产品 API 提供公开的产品数据,以便在客户端进行渲染。
列表产品
GET /products
GET /products?search=产品名称
GET /products?slug=别名-1,别名-2
GET /products?after=2017-03-22&date_column=日期
GET /products?before=2017-03-22&date_column=日期
GET /products?exclude=10,44,33
GET /products?include=10,44,33
GET /products?offset=10
GET /products?order=asc&orderby=价格
GET /products?parent=10
GET /products?parent_exclude=10
GET /products?type=simple
GET /products?sku=sku-1,sku-2
GET /products?featured=true
GET /products?category=22
GET /products?brand=adidas
GET /products?_unstable_tax_my-taxonomy=my-taxonomy-term-id
GET /products?tag=special-items
GET /products?attributes[0][attribute]=pa_color&attributes[0][slug]=red
GET /products?on_sale=true
GET /products?min_price=5000
GET /products?max_price=10000
GET /products?stock_status=['outofstock']
GET /products?catalog_visibility=search
GET /products?rating=4,5
GET /products?related=34
GET /products?return_price_range=true
GET /products?return_attribute_counts=pa_size,pa_color
GET /products?return_rating_counts=true
产品查询参数
以下参数可用于限制产品查询结果。
| 属性 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
search |
字符串 | 否 | 限制结果,仅包含匹配的字符串。 |
slug |
字符串 | 否 | 限制结果集,仅包含具有特定别名(s)的产品。 使用逗号分隔。 |
after |
字符串 | 否 | 限制响应,仅包含在给定符合ISO8601标准的日期之后创建的资源。 |
before |
字符串 | 否 | 限制响应,仅包含在给定符合ISO8601标准的日期之前创建的资源。 |
date_column |
字符串 | 否 | 当限制响应时,用于比较的日期列。 允许的值:date, date_gmt, modified, modified_gmt |
exclude |
数组 | 否 | 确保结果集排除特定的ID。 |
include |
数组 | 否 | 限制结果集,仅包含特定的ID。 |
offset |
整数 | 否 | 偏移结果集,从指定的项目数开始。 |
order |
字符串 | 否 | 指定排序属性的升序或降序。 允许的值:asc, desc |
orderby |
字符串 | 否 | 按照对象属性对集合进行排序。 允许的值:date, modified, id, include, title, slug, price, popularity, rating, menu_order, comment_count |
parent |
数组 | 否 | 限制结果集,仅包含特定父ID的产品。 |
parent_exclude |
数组 | 否 | 限制结果集,排除所有具有特定父ID的产品。 |
type |
字符串 | 否 | 限制结果集,仅包含分配了特定类型的的产品。 |
sku |
字符串 | 否 | 限制结果集,仅包含具有特定SKU(s)的产品。 使用逗号分隔。 |
featured |
布尔值 | 否 | 限制结果集,仅包含推荐的产品。 |
category |
字符串 | 否 | 限制结果集,仅包含分配到分类ID或别名(s)的产品,用逗号分隔。 |
category_operator |
字符串 | 否 | 用于比较产品分类的运算符。 允许的值:in, not_in, and |
brand |
字符串 | 否 | 限制结果集,仅包含分配到品牌ID或别名(s)的产品,用逗号分隔。 |
brand_operator |
字符串 | 否 | 用于比较产品品牌术语的运算符。 允许的值:in, not_in, and |
_unstable_tax_[product-taxonomy] |
字符串 | 否 | 限制结果集,仅包含分配到自定义产品分类术语ID的产品。 [product-taxonomy] 应该是已注册的自定义产品分类的键。 |
_unstable_tax_[product-taxonomy]_operator |
字符串 | 否 | 用于比较自定义产品分类术语的运算符。 允许的值:in, not_in, and |
tag |
字符串 | 否 | 限制结果集,仅包含分配了特定标签ID的产品。 |
tag_operator |
字符串 | 否 | 用于比较产品标签的运算符。 允许的值:in, not_in, and |
on_sale |
布尔值 | 否 | 限制结果集,仅包含正在促销的产品。 |
min_price |
字符串 | 否 | 限制结果集,仅包含基于最小价格的产品,价格使用货币的最小单位表示。 例如,对于使用两位小数的货币(如USD),提供10025表示100.25,对于使用零小数的货币(如JPY),提供1025表示1025。 |
max_price |
字符串 | 否 | 限制结果集,仅包含基于最大价格的产品,价格使用货币的最小单位表示。 例如,对于使用两位小数的货币(如USD),提供10025表示100.25,对于使用零小数的货币(如JPY),提供1025表示1025。 |
stock_status |
数组 | 否 | 限制结果集,仅包含具有指定库存状态的产品。 期望的是一个包含字符串的数组,字符串可以是'instock'、'outofstock'或'onbackorder'。 |
attributes |
数组 | 否 | 限制结果集,仅包含特定属性术语的产品。 期望的是一个对象数组,每个对象包含attribute(分类),term_id或slug,以及可选的operator用于比较。 |
attribute_relation |
字符串 | 否 | 当同时过滤多个属性时,属性之间的逻辑关系。 |
catalog_visibility |
字符串 | 否 | 确定是否显示隐藏或可见的目录产品。 允许的值:any, visible, catalog, search, hidden |
rating |
数组 | 否 | 限制结果集,仅包含具有特定平均评分的产品。 允许的值:1, 2, 3, 4, 5. |
related |
整数 | 否 | 限制结果集,仅包含与特定产品ID相关的产品。 |
产品信息示例
以下是一个产品信息的示例,展示了如何获取和显示产品数据。
示例响应:
[
{
"id": 34,
"name": "WordPress Pennant",
"slug": "wordpress-pennant",
"variation": "",
"permalink": "https://local.wordpress.test/product/wordpress-pennant/",
"sku": "wp-pennant",
"summary": "<p>This is an external product.</p>",
"short_description": "<p>This is an external product.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"on_sale": false,
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1105",
"regular_price": "1105",
"sale_price": "1105",
"price_range": null
},
"average_rating": "0",
"review_count": 0,
"images": [
{
"id": 57,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "pennant-1.jpg",
"alt": ""
}
],
"has_options": false,
"is_purchasable": true,
"is_in_stock": true,
"low_stock_remaining": null,
"add_to_cart": {
"text": "Add to cart",
"description": "Add “WordPress Pennant” to your cart"
}
}
]
字段说明:
id: 产品ID。name: 产品名称。slug: 产品的别名。variation: 产品的变体。permalink: 产品的固定链接。sku: 产品的库存单位。summary: 产品的摘要。short_description: 产品的简短描述。description: 产品的详细描述。on_sale: 是否正在促销。prices: 价格信息,包括货币代码、符号、小数位数、分隔符、前缀、后缀、价格、原价、折扣价和价格范围。average_rating: 平均评分。review_count: 评论数量。images: 产品图像列表。has_options: 是否有选项。is_purchasable: 是否可购买。is_in_stock: 是否有库存。low_stock_remaining: 库存剩余量(如果库存不足)。add_to_cart: "加入购物车"按钮的文本和描述。
如何获取产品信息:
可以使用以下 curl 命令从商店获取产品信息:
curl "https://example-store.com/wp-json/wc/store/v1/products"
示例:
Permalink: 固定链接Variation: 变体Link: 链接Slug: 别名External Product: 外部产品Add to Cart: 加入购物车Remaining: 剩余Currency: 货币Summary: 摘要Product: 产品Images: 图像Upload: 上传Prefix: 前缀Option: 选项Suffix: 后缀Width: 宽度Stock: 库存range: 范围Store: 商店Done: 完成
通过 ID 获取单个产品
获取指定 ID 的单个产品。
GET /products/:id
| 属性 | 类型 | 是否必选 | 描述 |
|---|---|---|---|
id |
integer | 是 | 要检索的产品的 ID。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/34"
示例响应:
{
"id": 34,
"name": "WordPress Pennant",
"slug": "wordpress-pennant",
"variation": "",
"permalink": "https://local.wordpress.test/product/wordpress-pennant/",
"sku": "wp-pennant",
"summary": "<p>This is an external product.</p>",
"short_description": "<p>This is an external product.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"on_sale": false,
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1105",
"regular_price": "1105",
"sale_price": "1105",
"price_range": null
},
"average_rating": "0",
"review_count": 0,
"images": [
{
"id": 57,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "pennant-1.jpg",
"alt": ""
}
],
"has_options": false,
"is_purchasable": true,
"is_in_stock": true,
"low_stock_remaining": null,
"add_to_cart": {
"text": "Add to cart",
"description": "Add “WordPress Pennant” to your cart"
}
}
通过别名获取单个产品
通过别名获取单个产品。
GET /products/:slug
| 属性 | 类型 | 是否必选 | 描述 |
|---|---|---|---|
slug |
string | 是 | 用于检索产品的别名。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/wordpress-pennant"
示例响应:
{
"id": 34,
"name": "WordPress Pennant",
"slug": "wordpress-pennant",
"variation": "",
"permalink": "https://local.wordpress.test/product/wordpress-pennant/",
"sku": "wp-pennant",
"summary": "<p>这是一个外部产品。</p>",
"short_description": "<p>这是一个外部产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"on_sale": false,
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1105",
"regular_price": "1105",
"sale_price": "1105",
"price_range": null
},
"average_rating": "0",
"review_count": 0,
"images": [
{
"id": 57,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "pennant-1.jpg",
"alt": ""
}
],
"has_options": false,
"is_purchasable": true,
"is_in_stock": true,
"low_stock_remaining": null,
"add_to_cart": {
"text": "加入购物车",
"description": "将“WordPress Pennant”添加到您的购物车"
}
}
产品链接和嵌入
产品响应包含 _links,其中提供指向相关资源的 URL。当产品配置了追加销售、交叉销售或相关产品时,会包含可嵌入的链接,这些链接可与 WordPress 的 _embed 功能一起使用。
可用的链接
| 链接 | 描述 | 可嵌入 |
|---|---|---|
self |
链接至当前产品 | No |
collection |
链接至产品集合 | No |
up |
链接至父产品 (用于变体) | No |
upsells |
链接用于获取追加销售产品 (如果已配置) | Yes |
cross_sells |
链接用于获取交叉销售产品 (如果已配置) | Yes |
related |
链接用于获取相关产品 | Yes |
包含链接的示例响应
{
"id": 34,
"name": "WordPress Pennant",
"_links": {
"self": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products/34"}],
"collection": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products"}],
"upsells": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products?include=10,20", "embeddable": true}],
"cross_sells": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products?include=30", "embeddable": true}],
"related": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products?related=34&per_page=10", "embeddable": true}]
}
}
使用 _embed 参数
向任何产品请求添加 ?_embed,即可自动获取并包含链接的资源,并将它们嵌入到 _embedded 对象中:
curl "https://local.wordpress.test/wp-json/wc/store/v1/products/34?_embed"
包含嵌入的示例响应:
{
"id": 34,
"name": "WordPress Pennant",
"_links": {
"self": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products/34"}],
"collection": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products"}],
"upsells": [{"href": "https://local.wordpress.test/wp-json/wc/store/v1/products?include=10,20", "embeddable": true}]
},
"_embedded": {
"upsells": [
{"id": 10, "name": "追加销售产品 1", "...": "..."},
{"id": 20, "name": "追加销售产品 2", "...": "..."}
]
}
}
产品变体
默认情况下,商店 API 排除产品变体。 您可以使用 type=variation 参数来检索产品的变体。
curl "https://example-store.com/wp-json/wc/store/v1/products?type=variation"
购物车 API
购物车 API 返回当前会话或登入用户的购物车当前状态。
所有 POST 端点都需要一个随机数令牌或一个购物车令牌,并在完成后返回完整购物车的已更新状态。
获取购物车
GET /cart
此端点无需任何参数。
curl "https://example-store.com/wp-json/wc/store/v1/cart"
返回完整的购物车对象回复(参见购物车回复)。
回复
所有 /cart 下的端点(本文档中列出的)均以相同格式返回回复;一个包含购物车项目、已应用优惠券、配送地址和费率,以及非敏感客户数据的购物车对象。
购物车回复
本节描述了购物车相关的回复。
请求参数:
cart_id: 购物车ID (整数)user_id: 用户ID (整数)
请求示例:
GET /api/v1/cart/%s?user_id=%d
回复格式:
{
"status": "success",
"data": {
"cart_id": %d,
"user_id": %d,
"items": [
{
"product_id": %d,
"quantity": %d
}
]
}
}
错误代码:
| 代码 | 描述 |
|---|---|
| 400 | 错误的请求参数。 |
| 401 | 未授权。 |
| 404 | 购物车不存在。 |
| 500 | 服务器内部错误。 |
示例回复:
{
"status": "success",
"data": {
"cart_id": 123,
"user_id": 456,
"items": [
{
"product_id": 789,
"quantity": 2
}
]
}
}
错误回复示例:
{
"status": "error",
"code": 404,
"message": "Cart not found."
}
注意事项:
status字段表示请求是否成功。data字段包含购物车信息。code字段表示错误代码。message字段包含错误信息。
其他:
on状态表示购物车已启用。off状态表示购物车已禁用。
函数:
get_cart_response(cart_id, user_id): 获取购物车回复。create_cart(user_id): 创建新的购物车。update_cart_item(cart_id, product_id, quantity): 更新购物车中的商品数量。delete_cart_item(cart_id, product_id): 从购物车中删除商品。clear_cart(cart_id): 清空购物车。
{
"items": [
{
"key": "a5771bce93e200c36f7cd9dfd0e5deaa",
"id": 38,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 9999,
"multiple_of": 1,
"editable": true
},
"name": "带有Logo的帽子",
"short_description": "<p>这是一个简单的产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "Woo-beanie-logo",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/beanie-with-logo/",
"images": [
{
"id": 61,
"src": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-450x450.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-450x450.jpg 450w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-600x600.jpg 600w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2023/03/beanie-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "beanie-with-logo-1.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "1800",
"regular_price": "2000",
"sale_price": "1800",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "18000000",
"regular_price": "20000000",
"sale_price": "18000000"
}
},
"totals": {
"line_subtotal": "1800",
"line_subtotal_tax": "180",
"line_total": "1530",
"line_total_tax": "153",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {}
},
{
"key": "b6d767d2f8ed5d21a44b0e5886680cb9",
"id": 22,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 9999,
"multiple_of": 1,
"editable": true
},
"name": "腰带",
"short_description": "<p>这是一个简单的产品。</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-belt",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/belt/",
"images": [
{
"id": 51,
"src": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-450x450.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2023/03/belt-2.jpg 801w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-450x450.jpg 450w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-600x600.jpg 600w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2023/03/belt-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "belt-2.jpg",
"alt": ""
}
],
"variation": [],
"item_data": [],
"prices": {
"price": "5500",
"regular_price": "6500",
"sale_price": "5500",
"price_range": null,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": "",
"raw_prices": {
"precision": 6,
"price": "55000000",
"regular_price": "65000000",
"sale_price": "55000000"
}
},
"totals": {
"line_subtotal": "5500",
"line_subtotal_tax": "550",
"line_total": "4675",
"line_total_tax": "468",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"catalog_visibility": "visible",
"extensions": {}
}
],
"coupons": [
{
"code": "test",
"discount_type": "percent",
"totals": {
"total_discount": "1095",
"total_discount_tax": "109",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
}
}
],
"fees": [],
"totals": {
"total_items": "7300",
"total_items_tax": "730",
"total_fees": "0",
"total_fees_tax": "0",
"total_discount": "1095",
"total_discount_tax": "110",
"total_shipping": "1300",
"total_shipping_tax": "130",
"total_price": "8256",
"total_tax": "751",
"tax_lines": [
{
"name": "税费",
"price": "751",
"rate": "10%"
}
],
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"shipping_address": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US",
"phone": "123456778"
},
"billing_address": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US",
"email": "checkout@templates.com",
"phone": "123456778"
},
"needs_payment": true,
"needs_shipping": true,
"payment_requirements": [ "products" ],
"has_calculated_shipping": true,
"shipping_rates": [
{
"package_id": 0,
"name": "Shipment 1",
"destination": {
"address_1": "Hello street",
"address_2": "",
"city": "beverly hills",
"state": "CA",
"postcode": "90211",
"country": "US"
},
"items": [
{
"key": "a5771bce93e200c36f7cd9dfd0e5deaa",
"name": "带有Logo的帽子",
"quantity": 1
},
{
"key": "b6d767d2f8ed5d21a44b0e5886680cb9",
"name": "腰带",
"quantity": 1
}
],
"shipping_rates": [
{
"rate_id": "flat_rate:10",
"name": "统一费率",
"description": "",
"delivery_time": "",
"price": "1300",
"taxes": "130",
"instance_id": 10,
"method_id": "flat_rate",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": true,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
{
"rate_id": "free_shipping:12",
"name": "免费配送",
"description": "",
"delivery_time": "",
"price": "0",
"taxes": "0",
"instance_id": 12,
"method_id": "free_shipping",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": false,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
{
"rate_id": "local_pickup:13",
"name": "本地自提",
"description": "",
"delivery_time": "",
"price": "0",
"taxes": "0",
"instance_id": 13,
"method_id": "local_pickup",
"meta_data": [
{
"key": "Items",
"value": "带有Logo的帽子 × 1, 腰带 × 1"
}
],
"selected": false,
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
}
]
}
],
"items_count": 2,
"items_weight": 0,
"cross_sells": [],
"errors": [],
"payment_methods": [ "bacs", "cod" ],
"extensions": {}
}
错误回复
如果无法执行购物车操作,将返回一个错误回复。 这将包含一个错误代码和一个错误消息:
{
"code": "woocommerce_rest_cart_invalid_product",
"message": "该产品无法添加到购物车。",
"data": {
"status": 400
}
}
某些错误回复表示冲突(错误 409),例如,当某个项目无法找到或优惠券不再生效时。 当返回此类回复时,服务器的购物车当前状态也会作为错误数据的一部分返回:
{
"code": "woocommerce_rest_cart_invalid_key",
"message": "购物车项目不再存在或无效。",
"data": {
"status": 409,
"cart": { ... }
}
}
这允许客户端在不发出额外请求的情况下,与购物车数据保持同步,即使购物车发生更改或已过期。
添加项目
将项目添加到购物车,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此端点将返回一个错误。
POST /cart/add-item
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer | 是 | 购物车中商品的 ID 或变体 ID。 |
quantity |
integer | 是 | 购物车中此商品的数量。 |
variation |
array | 是 | 选择的属性(用于变体),包含一个对象数组,每个对象包含键 attribute 和 value。 请注意,关于属性命名的说明见下文。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/add-item?id=100&quantity=1
如果成功,则返回完整的 购物车响应;如果失败,则返回一个 错误响应。
如果您希望在将购物车项目数据传递给 CartController::add_to_cart 之前添加补充数据,可以使用 woocommerce_store_api_add_to_cart_data 过滤器。 例如:
add_filter( 'woocommerce_store_api_add_to_cart_data', function( $add_to_cart_data, \WP_REST_Request $request ) {
if ( ! empty( $request['custom-request-param'] ) ) {
$add_to_cart_data['cart_item_data']['custom-request-data'] = sanitize_text_field( $request['custom-request-param'] );
}
return $add_to_cart_data;
}, 10, 2 );
变体属性命名:
在将变体添加到购物车时,属性的命名非常重要。
对于全局属性,发布到 API 的属性应该是属性的别名。 应该有一个 pa_ 前缀。 例如,如果您的属性名为 Color,则别名为 pa_color。
对于特定于产品的属性,发布到 API 的属性可以是以下之一:
- 属性的名称。 例如,如果您的属性名为
Size,则名称为Size。 这对大小写敏感。 - 属性的别名。 例如,如果您的属性名为
Autograph ✏️,则名称为attribute_autograph-%e2%9c%8f%ef%b8%8f。 这对大小写敏感。 您可以从产品页面的相关select中获取此别名。
示例 POST 请求体:
# 添加商品变体到购物车
以下示例向购物车添加了一个商品变体,该变体具有尺寸和颜色等属性。
**批量操作:**
如果您想一次性添加多个项目,则需要使用批量接口:
```http
POST /wc/store/v1/batch
向购物车添加多个项目的 JSON 数据格式如下:
{
"requests": [
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 26,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
},
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 27,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
}
]
}
{
"id": 13,
"quantity": 1,
"variation": [
{
"attribute": "pa_color",
"value": "blue"
},
{
"attribute": "attribute_autograph-%e2%9c%8f%ef%b8%8f",
"value": "Yes"
},
{
"attribute": "Logo",
"value": "Yes"
}
]
}
该示例添加了一个具有尺寸和颜色属性的产品变体到购物车。
Batching:
如果您想一次添加多个项目,您需要使用批量接口:
POST /wc/store/v1/batch
用于向购物车添加多个项目的 JSON 数据如下:
{
"requests": [
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 26,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
},
{
"path": "/wc/store/v1/cart/add-item",
"method": "POST",
"cache": "no-store",
"body": {
"id": 27,
"quantity": 1
},
"headers": {
"Nonce": "1db1d13784"
}
}
]
}
解释:
Variation: 变体Nonce: 随机数Attribute: 属性Quantity: 数量Requests: 请求Product: 产品Method: 方法Cache: 缓存Color: 颜色Value: 价值Store: 商店Path: 路径Auto: 自动Blue: 蓝色Cart: 购物车Item: 项目Log: 日志and: 和Use: 使用For: 为
移除项目
从购物车中移除一个项目并返回完整的购物车响应,或一个错误。
除非提供有效的随机数令牌或购物车令牌,否则此端点将返回一个错误。
POST /cart/remove-item
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的关键字。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/remove-item?key=e369853df766fa44e1ed0ff613f563bd
更新项目
更新购物车中的项目并返回完整的购物车响应,或错误信息。
除非提供有效的随机数令牌或购物车令牌,否则此端点将返回错误。
POST /cart/update-item
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 要编辑的购物车项目的键。 |
quantity |
整数 | 是 | 此项目在购物车中的数量。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/update-item?key=e369853df766fa44e1ed0ff613f563bd&quantity=10
应用优惠券
将优惠券应用于购物车并返回完整的购物车响应,或一个错误。
除非提供了有效的随机数令牌或购物车令牌,否则此端点将返回一个错误。
POST /cart/apply-coupon/
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望应用于购物车的优惠券代码。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/apply-coupon?code=20off
移除优惠券
从购物车中移除一个优惠券,并返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 或 购物车令牌,否则此接口将返回一个错误。
POST /cart/remove-coupon/
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
code |
字符串 | 是 | 您希望从购物车中移除的优惠券代码。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/cart/remove-coupon?code=20off
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
更新客户信息
更新客户信息,并返回完整的购物车信息,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此 API 将返回一个错误。
POST /cart/update-customer
客户地址信息
本节描述了客户地址信息的结构。
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
billing_address |
object | 否 | 客户的账单地址。 |
billing_address.first_name |
string | 否 | 客户的名。 |
billing_address.last_name |
string | 否 | 客户的姓氏。 |
billing_address.address_1 |
string | 否 | 配送地址的第一行。 |
billing_address.address_2 |
string | 否 | 配送地址的第二行。 |
billing_address.city |
string | 否 | 配送地址的城市。 |
billing_address.state |
string | 否 | 州、省或地区的 ISO 代码,或名称,用于表示配送地址。 |
billing_address.postcode |
string | 否 | 配送地址的邮政编码。 |
billing_address.country |
string | 否 | 配送地址所在国家的 ISO 代码。 |
billing_address.email |
string | 否 | 客户的邮件地址。 |
billing_address.phone |
string | 否 | 客户的电话号码。 |
shipping_address |
object | 否 | 客户的配送地址。 |
shipping_address.first_name |
string | 否 | 客户的名。 |
shipping_address.last_name |
string | 否 | 客户的姓氏。 |
shipping_address.address_1 |
string | 否 | 配送地址的第一行。 |
shipping_address.address_2 |
string | 否 | 配送地址的第二行。 |
shipping_address.city |
string | 否 | 配送地址的城市。 |
shipping_address.state |
string | 否 | 州、省或地区的 ISO 代码,或名称,用于表示配送地址。 |
shipping_address.postcode |
string | 否 | 配送地址的邮政编码。 |
shipping_address.country |
string | 否 | 配送地址所在国家的 ISO 代码。 |
以下是一些示例:
# 示例 1: 创建一个包含账单地址和配送地址的客户对象。
customer = {
"billing_address": {
"first_name": "名",
"last_name": "姓氏",
"address_1": "地址",
"address_2": "",
"city": "城市",
"state": "州",
"postcode": "邮政编码",
"country": "国家",
"email": "邮件",
"phone": "电话号码"
},
"shipping_address": {
"first_name": "名",
"last_name": "姓氏",
"address_1": "地址",
"address_2": "",
"city": "城市",
"state": "州",
"postcode": "邮政编码",
"country": "国家"
}
}
# 示例 2: 设置一个客户的属性。
set_customer_attribute(customer, "description", "描述")
# 示例 3: 获取一个数值。
number = get_number()
# 示例 4: 循环 %d 秒。
for i in range(1, %d):
print("一 %s 秒" % "second")
# 示例 5: 检查一个条件。
if no:
print("否")
else:
print("是")
# 示例 6: 使用 Code
请注意,String 是一个 String 类型。 Phone Number 必须是有效的 Phone Number。 First name 不能为空。 Attribute 必须是有效的 Attribute。 Last Name 不能为空。 Shipping 必须是有效的 Shipping 地址。 Address 必须是有效的 Address。 Second 表示 Second。 number 表示 number。 Code 表示 Code。 Mail 表示 Mail。 Red 表示 Red。 one 表示 one。 For 表示 For。 In 表示 In。 No 表示 No。 Shipping Address 表示 Shipping Address。 Description 表示 Description。 Customer 表示 Customer。
返回全部的 购物车回复,如果成功;否则,返回一个 错误回复。
选择配送费率
选择一个可用的配送费率,然后返回完整的购物车响应,或者返回一个错误。
除非提供了有效的 随机数 Token 或 购物车 Token,否则此接口将返回一个错误。
POST /cart/select-shipping-rate
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
package_id |
integer | 是 | 购物车中配送包的 ID。 |
rate_id |
string | 是 | 选定的配送包的费率 ID。 |
curl --header "Nonce: 12345" --request POST /cart/select-shipping-rate?package_id=1&rate_id=flat_rate:1
在成功时,返回完整的 购物车响应,在失败时,返回一个 错误响应。
结账订单 API
结账订单 API 旨在简化现有订单的处理和付款操作。
所有结账订单接口都需要一个 随机数 Token 或一个 购物车 Token,否则这些接口将返回一个错误。
处理订单和支付
接受最终选择的支付方法,以及任何额外的支付数据,然后尝试支付并返回结果。
POST /wc/store/v1/checkout/{ORDER_ID}
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
key |
字符串 | 是 | 用于订单验证的密钥。 |
billing_email |
字符串 | 否 | 用于验证访客订单的 Email 地址。 |
billing_address |
对象 | 是 | 客户已更新的账单地址数据对象。 |
shipping_address |
对象 | 是 | 客户已更新的配送地址数据对象。 |
payment_method |
字符串 | 是 | 用于处理支付的支付方法 ID。 |
payment_data |
数组 | 否 | 在处理支付时传递给支付方法的数据。 |
curl --header "Nonce: 12345" --request POST https://example-store.com/wp-json/wc/store/v1/checkout/{ORDER_ID} -d '{"key":"wc_order_oFmQYREzh9Tfv","billing_email":"admin@example.com","payment_method":"cheque","billing_address":{...},"shipping_address":{...}'
示例请求:
{
"key": "wc_order_oFmQYREzh9Tfv",
"billing_email": "admin@example.com",
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"payment_method": "cheque",
"payment_data": []
}
示例响应:
# 订单详情
以下是订单的详细信息。
**订单 ID:** %d
**状态:** %s
## 订单概览
* **订单 ID:** %d
* **状态:** %s
* **订单 Key:** %s
* **客户备注:** %s
* **客户 ID:** %d
## 账单地址
* **地址:**
* **姓名:** %s
* **公司:** %s
* **地址 1:** %s
* **地址 2:** %s
* **城市:** %s
* **州/省:** %s
* **邮编:** %s
* **国家:** %s
* **邮箱:** %s
* **电话:** %s
## 配送地址
* **地址:**
* **姓名:** %s
* **公司:** %s
* **地址 1:** %s
* **地址 2:** %s
* **城市:** %s
* **州/省:** %s
* **邮编:** %s
* **国家:** %s
* **电话:** %s
## 支付信息
* **支付方法:** %s
* **支付结果:**
* **支付状态:** %s
* **支付详情:** %s
* **重定向 URL:** %s
## 订单管理
* **管理员:** 只有管理员才能查看和修改订单信息。
* **检查:** 定期检查订单状态,确保顺利完成。
* **锁定:** 在处理订单时,可以锁定订单以防止其他用户修改。
* **邮件:** 系统会发送邮件通知客户订单状态更新。
* **新增:** 管理员可以新增订单。
* **红色:** 某些情况下,订单状态会显示为红色,表示存在问题。
* **网址:** 请注意以下网址。
* **关键字:** 使用关键字进行订单搜索。
```json
{
"order_id": 146,
"status": "on-hold",
"order_key": "wc_order_oFmQYREzh9Tfv",
"customer_note": "",
"customer_id": 1,
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"payment_method": "cheque",
"payment_result": {
"payment_status": "success",
"payment_details": [],
"redirect_url": "https://local.wordpress.test/block-checkout/order-received/146/?key=wc_order_VPffqyvgWVqWL"
}
}
常见问题
- 如何修改订单信息? 只有管理员可以修改订单信息。
- 如何取消订单? 请联系客服进行取消。
- 如何查看订单状态? 您可以在账户中查看订单状态。
- 如何进行退货? 请参考我们的退货政策。
- 配送时间是多久? 配送时间取决于您的地址和选择的配送方式。
- 结账时遇到了问题,怎么办? 请联系客服寻求帮助。
- 如何联系客服? 您可以通过邮件或电话联系客服。
- 测试环境: 这是测试环境,所有数据均为测试数据。
## 支付数据
有很多支付网关可供商家使用,并且每个网关都期望接收不同的 `payment_data`。 我们无法全面列出所有支付网关期望的所有请求,因此我们建议您联系您正在使用的支付网关插件的作者,以获取更多信息。
以下是一个使用 [WooCommerce Stripe 支付网关](https://wordpress.org/plugins/woocommerce-gateway-stripe/) 时,发送到结账订单端点的支付数据的示例。
有关生成 `stripe_source` 的更多信息,请查看 [Stripe 文档](https://stripe.com/docs)。
```json
{
"payment_data": [
{
"key": "stripe_source",
"value": "src_xxxxxxxxxxxxx"
},
{
"key": "billing_email",
"value": "myemail@email.com"
},
{
"key": "billing_first_name",
"value": "Jane"
},
{
"key": "billing_last_name",
"value": "Doe"
},
{
"key": "paymentMethod",
"value": "stripe"
},
{
"key": "paymentRequestType",
"value": "cc"
},
{
"key": "wc-stripe-new-payment-method",
"value": true
}
]
}
订单 API
订单 API 返回用于支付的订单。
获取订单
GET /order/{ORDER_ID}?key={KEY}&billing_email={BILLING_EMAIL}
此端点有一个必填参数,即 key。对于访客订单,必须添加 billing_email。
curl "https://example-store.com/wp-json/wc/store/v1/order/{ORDER_ID}?key={KEY}&billing_email={BILLING_EMAIL}"
返回完整的订单对象回复(参见订单回复)。
回复
订单端点返回的回复格式与 /cart 相同;一个订单对象,其中包含订单项目、已应用的优惠券、配送地址和费率,以及非敏感的客户数据。
订单回复
本节描述了系统对订单的回复。
响应格式
回复采用以下 JSON 格式:
{
"status": "success" | "failed",
"order_id": "%s",
"message": "操作成功" | "订单不存在" | "支付失败" | "其他错误信息"
}
status: 表示操作的成功或失败。order_id: 订单的唯一标识符。message: 包含操作结果的详细信息。
成功回复 (status: success)
当订单处理成功时,系统会返回以下回复:
{
"status": "success",
"order_id": "%s",
"message": "操作成功"
}
失败回复 (status: failed)
当订单处理失败时,系统会返回以下回复:
{
"status": "failed",
"order_id": "%s",
"message": "订单不存在" | "支付失败" | "其他错误信息"
}
错误处理
如果出现错误,系统会返回 status: failed 的回复,并包含详细的错误信息。 例如,如果订单不存在,系统会返回:
{
"status": "failed",
"order_id": "%s",
"message": "订单不存在"
}
API 使用示例
以下是一个使用 getOrderResponse 函数的示例:
def getOrderResponse(order_id):
"""
获取订单的回复。
Args:
order_id: 订单的 ID。
Returns:
一个包含回复信息的字典。
"""
# ... (省略实现细节) ...
return {
"status": "success",
"order_id": order_id,
"message": "操作成功"
}
其他说明
getOrderResponse函数可能返回不同的message值,具体取决于订单的状态。- 如果
order_id无效,getOrderResponse函数会返回status: failed的回复。 - 系统会记录所有订单操作,包括成功和失败的回复。
%s是一个占位符,表示要插入的字符串值。{name}是一个占位符,表示要插入的变量名。Or表示“或”。on表示“开”。Response表示“回复”。
{
"id": 147,
"status": "待审",
"coupons": [
{
"code": "discount20",
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"total_discount": "421",
"total_discount_tax": "0"
}
}
],
"shipping_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"phone": "555-2368"
},
"billing_address": {
"first_name": "Peter",
"last_name": "Venkman",
"company": "",
"address_1": "550 Central Park West",
"address_2": "Corner Penthouse Spook Central",
"city": "New York",
"state": "NY",
"postcode": "10023",
"country": "US",
"email": "admin@example.com",
"phone": "555-2368"
},
"items": [
{
"key": "9bf31c7ff062936a96d3c8bd1f8f2ff3",
"id": 15,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 99,
"multiple_of": 1,
"editable": true
},
"name": "Beanie",
"short_description": "<p>This is a simple product.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "woo-beanie",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/beanie/",
"images": [
{
"id": 44,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2.jpg 801w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/beanie-2-768x768.jpg 768w",
"sizes": "(max-width: 801px) 100vw, 801px",
"name": "beanie-2.jpg",
"alt": ""
}
],
"variation": [],
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1000",
"regular_price": "2000",
"sale_price": "1000",
"price_range": null,
"raw_prices": {
"precision": 6,
"price": "10000000",
"regular_price": "20000000",
"sale_price": "10000000"
}
},
"item_data": [],
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"line_subtotal": "1000",
"line_subtotal_tax": "0",
"line_total": "800",
"line_total_tax": "0"
},
"catalog_visibility": "view"
},
{
"key": "e369853df766fa44e1ed0ff613f563bd",
"id": 34,
"quantity": 1,
"quantity_limits": {
"minimum": 1,
"maximum": 99,
"multiple_of": 1,
"editable": true
},
"name": "WordPress Pennant",
"short_description": "<p>This is an 外部产品.</p>",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>",
"sku": "wp-pennant",
"low_stock_remaining": null,
"backorders_allowed": false,
"show_backorder_badge": false,
"sold_individually": false,
"permalink": "https://local.wordpress.test/product/wordpress-pennant/",
"images": [
{
"id": 57,
"src": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg",
"thumbnail": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg",
"srcset": "https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1.jpg 800w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-324x324.jpg 324w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-100x100.jpg 100w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-416x416.jpg 416w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-300x300.jpg 300w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-150x150.jpg 150w, https://local.wordpress.test/wp-content/uploads/2020/03/pennant-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "pennant-1.jpg",
"alt": ""
}
],
"variation": [],
"prices": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"price": "1105",
"regular_price": "1105",
"sale_price": "1105",
"price_range": null,
"raw_prices": {
"precision": 6,
"price": "11050000",
"regular_price": "11050000",
"sale_price": "11050000"
}
},
"item_data": [],
"totals": {
"currency_code": "GBP",
"currency_symbol": "£",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "£",
"currency_suffix": "",
"line_subtotal": "1105",
"line_subtotal_tax": "0",
"line_total": "884",
"line_total_tax": "0"
},
"catalog_visibility": "view"
}
],
"needs_payment": true,
"needs_shipping": true,
"totals": {
"subtotal":"2105",
"total_discount": "421",
"total_shipping": "500",
"total_fees": "0",
"total_tax": "0",
"total_refund": "0",
"total_price": "2184",
"total_items": "2105",
"total_items_tax": "0",
"total_fees_tax": "0",
"total_discount_tax": "0",
"total_shipping_tax": "0",
"tax_lines": []
},
"errors": [],
"payment_requirements": [ "products" ],
}
错误回复
如果无法执行某个订单操作,将会返回一个错误回复。该回复将包含一个原因代码和一个错误信息:
{
"code": "woocommerce_rest_invalid_order",
"message": "提供的订单 ID 或关键字无效。",
"data": {
"status": 401
}
}
产品 属性 术语 API
GET /products/attributes/:id/terms
GET /products/attributes/:id/terms?orderby=slug
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
id |
integer | 是 | 要获取术语的属性的 ID。 |
order |
string | 否 | 升序或降序排序。 允许的值:asc, desc |
orderby |
string | 否 | 按对象属性排序集合。 允许的值:id, name, name_num, slug, count, menu_order. |
curl "https://example-store.com/wp-json/wc/store/v1/products/attributes/1/terms"
示例响应:
[
{
"id": 22,
"name": "Blue",
"slug": "blue",
"count": 5
},
{
"id": 48,
"name": "Burgundy",
"slug": "burgundy",
"count": 1
}
]
产品品牌 API
列出产品品牌
GET /products/brands
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
context |
字符串 | 否 | 发起请求的范围;决定响应中包含的字段。 |
page |
整数 | 否 | 集合的当前页。默认为 1。 |
per_page |
整数 | 否 | 结果集中返回的最大项目数。默认为无限制。允许 0 到 100 之间的数值。 |
search |
字符串 | 否 | 将结果限制为匹配某个字符串的项目。 |
exclude |
数组 | 否 | 确保结果集排除特定的 ID。 |
include |
数组 | 否 | 将结果集限制为特定的 ID。 |
order |
字符串 | 否 | 升序或降序排序。允许的值:asc, desc。默认为 asc。 |
orderby |
字符串 | 否 | 按术语属性排序。允许的值:name, slug, count。默认为 name。 |
hide_empty |
布尔值 | 否 | 如果为 true,则不返回空术语。默认为 true。 |
parent |
整数 | 否 | 将结果限制为具有特定父级 ID 的项目。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/brands"
示例响应:
[
{
"id": 16,
"name": "Nike",
"slug": "nike",
"description": "This is the Nike brand.",
"parent": 0,
"count": 11,
"image": {
"id": 55,
"src": "https://store.local/wp-content/uploads/2021/11/nike-logo.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/nike-logo-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/nike-logo.jpg 800w, https://store.local/wp-content/uploads/2021/11/nike-logo-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/nike-logo-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/nike-logo-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/nike-logo-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/nike-logo-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/nike-logo-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "nike-logo.jpg",
"alt": ""
},
"review_count": 2,
"permalink": "https://store.local/product-brand/nike/"
},
{
"id": 21,
"name": "Adidas",
"slug": "adidas",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-brand/adidas/"
}
]
单个品牌
获取单个品牌信息。
GET /products/brands/:id
或者
GET /products/brands/:slug
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
identifier |
字符串 | 是 | 用于获取品牌的标识符。可以是品牌 ID 或别名。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/brands/1"
或者
curl "https://example-store.com/wp-json/wc/store/v1/products/brands/adidas"
示例回复:
{
"id": 1,
"name": "Adidas",
"slug": "adidas",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-brand/adidas/"
}
产品分类 API
列出产品分类
GET /products/categories
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
context |
字符串 | 否 | 发起请求的范围;决定响应中包含的字段。 |
page |
整数 | 否 | 集合的当前页。默认为 1。 |
per_page |
整数 | 否 | 结果集中返回的最大项目数。默认为无限制。允许 0 到 100 之间的值。 |
search |
字符串 | 否 | 将结果限制为匹配特定字符串的项目。 |
exclude |
数组 | 否 | 确保结果集排除特定的 ID。 |
include |
数组 | 否 | 将结果集限制为特定的 ID。 |
order |
字符串 | 否 | 升序或降序排序。允许的值:asc, desc。默认为 asc。 |
orderby |
字符串 | 否 | 按术语属性排序。允许的值:name, slug, count。默认为 name。 |
hide_empty |
布尔值 | 否 | 如果为 true,则不返回空术语。默认为 true。 |
parent |
整数 | 否 | 将结果限制为具有特定父级 ID 的项目。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/categories"
示例响应:
[
{
"id": 16,
"name": "Clothing",
"slug": "clothing",
"description": "This is the clothing category.",
"parent": 0,
"count": 11,
"image": {
"id": 55,
"src": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1.jpg 800w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/t-shirt-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "t-shirt-with-logo-1.jpg",
"alt": ""
},
"review_count": 2,
"permalink": "https://store.local/product-category/clothing/"
},
{
"id": 21,
"name": "Decor",
"slug": "decor",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-category/decor/"
}
]
产品分类
获取单个分类。
GET /products/categories/:id
| 分类 | 类型 | 必填 | 描述 |
|---|---|---|---|
id |
整数 | 是 | 要检索的分类的 ID。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/categories/1"
示例回复:
{
"id": 1,
"name": "Decor",
"slug": "decor",
"description": "",
"parent": 0,
"count": 1,
"image": null,
"review_count": 1,
"permalink": "https://store.local/product-category/decor/"
}
产品评论 API
列出产品评论
此端点返回产品评论(评论),也可以显示来自特定产品或特定分类的结果。
GET /products/reviews
GET /products/reviews?category_id=1,2,3
GET /products/reviews?product_id=1,2,3
GET /products/reviews?orderby=rating&order=desc
| 属性 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
page |
integer | 否 | 集合的当前页。 |
per_page |
integer | 否 | 结果集中要返回的最大项目数。 |
offset |
integer | 否 | 将结果集偏移特定数量的项目。 |
order |
string | 否 | 排序属性升序或降序。允许的值:asc, desc |
orderby |
string | 否 | 按对象属性对集合进行排序。允许的值:date, date_gmt, id, rating, product |
category_id |
string | 否 | 将结果集限制为来自特定分类 ID 的评论。 |
product_id |
string | 否 | 将结果集限制为来自特定产品 ID 的评论。 |
curl "https://example-store.com/wp-json/wc/store/v1/products/collection-data?calculate_price_range=true&calculate_attribute_counts=pa_size,pa_color&calculate_rating_counts=true"
示例响应:
[
{
"id": 83,
"date_created": "2022-01-12T15:42:14",
"formatted_date_created": "January 12, 2022",
"date_created_gmt": "2022-01-12T15:42:14",
"product_id": 33,
"product_name": "Beanie with Logo",
"product_permalink": "https://store.local/product/beanie-with-logo/",
"product_image": {
"id": 56,
"src": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1.jpg",
"thumbnail": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-324x324.jpg",
"srcset": "https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1.jpg 800w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-324x324.jpg 324w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-100x100.jpg 100w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-416x416.jpg 416w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-300x300.jpg 300w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-150x150.jpg 150w, https://store.local/wp-content/uploads/2021/11/beanie-with-logo-1-768x768.jpg 768w",
"sizes": "(max-width: 800px) 100vw, 800px",
"name": "beanie-with-logo-1.jpg",
"alt": ""
},
"reviewer": "reviewer-name",
"review": "<p>This is a fantastic product.</p>\n",
"rating": 5,
"verified": true,
"reviewer_avatar_urls": {
"24": "https://secure.gravatar.com/avatar/12345?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/12345?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/12345?s=96&d=mm&r=g"
}
}
]
购物车令牌
获取购物车令牌
对 /cart 接口的请求会返回一个 Cart-Token 头部,该头部包含一个令牌,该令牌可以在后续的请求中作为头部发送到 API 商店的购物车和结账接口,以标识购物车。
获取购物车令牌最快的方法是发送一个 GET 请求到 /wp-json/wc/store/v1/cart,并观察响应头部。 您应该在该头部中看到一个 Cart-Token。
如何使用 Cart-Token
要使用 Cart-Token,请将其包含在请求的头部中。 响应将包含与 Cart-Token 关联的会话的当前购物车状态。
示例:
curl --header "Cart-Token: 12345" --request GET https://example-store.com/wp-json/wc/store/v1/cart
使用相同的方法,您可以使用 Cart-Token 在 /checkout 路由上进行结账。
WooCommerce 编码规范
遵守 WooCommerce 编码规范对于维护高质量的代码、确保兼容性以及促进更轻松的维护和更新至关重要。本文档概述了在 WooCommerce 生态系统中工作的开发人员应遵循的推荐编码实践,包括使用钩子、函数前缀、可翻译文本以及代码结构。
钩子的位置
将钩子放置在函数调用下方,以符合 WordPress 和 WooCommerce 生态系统中常见的模式。
示例:
/**
* 添加自定义消息。
*/
function YOUR_PREFIX_custom_message() {
echo 'This is a custom message';
}
add_action( 'wp_footer', 'YOUR_PREFIX_custom_message' );
函数调用前缀
为所有函数调用使用一致的前缀,以避免冲突。对于此仓库中的代码片段,请使用 YOUR_PREFIX。
示例:
/**
* 添加自定义折扣。
*/
function YOUR_PREFIX_custom_discount( $price, $product ) {
return $price * 0.9; // 10% discount
}
add_filter( 'woocommerce_product_get_price', 'YOUR_PREFIX_custom_discount', 10, 2 );
可翻译文本和文本域
确保所有纯文本都是可翻译的,并使用一致的文本域,遵循国际化最佳实践。对于此仓库中的代码片段,请使用文本域 YOUR-TEXTDOMAIN。
示例:
/**
* 添加欢迎消息。
*/
function YOUR_PREFIX_welcome_message() {
echo __( 'Welcome to our website', 'YOUR-TEXTDOMAIN' );
}
add_action( 'wp_footer', 'YOUR_PREFIX_welcome_message' );
使用 function_exists()
为了防止潜在的函数重定义导致错误,请将所有函数调用包装在 function_exists() 中。
示例:
/**
* 添加缩略图支持。
*/
if ( ! function_exists( 'YOUR_PREFIX_theme_setup' ) ) {
function YOUR_PREFIX_theme_setup() {
add_theme_support( 'post-thumbnails' );
}
}
add_action( 'after_setup_theme', 'YOUR_PREFIX_theme_setup' );
代码质量标准
为了确保最高的代码质量标准,鼓励开发人员遵循以下实践:
WooCommerce 代码检查和 WordPress 代码标准
- 确保代码通过 WooCommerce 代码检查和 WordPress 代码标准,使用 PHP_CodeSniffer。
自动化测试
- 单元测试: 实施自动化单元测试,以验证代码在隔离环境中的功能。
- 端到端测试: 使用自动化端到端测试,以验证应用程序中组件的集成操作。
跟踪和管理错误
- 监控并努力减少 打开的错误数量,以确保产品稳定可靠。
代码组织
- 将代码组织到独立的类中,以避免创建包含所有插件代码的“万能类”。 这种做法有助于提高模块化程度,并简化维护。
通过遵循这些编码标准和实践,开发者可以创建高质量、可维护且安全的 WooCommerce 扩展,从而为 WordPress 生态系统做出积极的贡献。
CSS/Sass 命名规范
简介
我们的规范基于 Calypso 的规范,而 Calypso 又遵循 BEM 方法论。
请参考 Calypso CSS/Sass 编码规范 以获取完整详情。
更多关于 BEM 核心概念 的信息,请阅读相关文档。
在 WooCommerce 中,有一些与上述规范略有不同的地方,具体内容如下所述。
前缀
由于 WooCommerce 是一个 WordPress 插件,因此必须与 WordPress 核心以及其他插件/主题兼容。为了最大限度地减少潜在的冲突,所有类名都应以 .woocommerce- 开头。
类名
在命名类名时,请记住以下几点:
- Block (块) - 独立的实体,本身具有意义。例如,组件的名称。
- Element (元素) - 块的组成部分,本身没有独立意义。它们在语义上与所属的块相关联。
- Modifier (修饰符) - 用于块或元素的标志。使用它们来改变外观或行为。
示例
/* Block (块) */
.woocommerce-loop {}
/* Nested block (嵌套块) */
.woocommerce-loop-product {}
/* Modifier (修饰符) */
.woocommerce-loop-product--sale {}
/* Element (元素) */
.woocommerce-loop-product__link {}
/* Element (元素) */
.woocommerce-loop-product__button-add-to-cart {}
/* Modifier (修饰符) */
.woocommerce-loop-product__button-add-to-cart--added {}
注意: .woocommerce-loop-product 并非以这种方式命名,因为该块嵌套在 .woocommerce-loop 内部。 这样做是为了更具体,以便我们能够为单个产品、购物车产品等设置单独的类名。 嵌套块不需要继承其父级的全名。
总结
- 除非与此处的内容相矛盾,否则请遵循 WordPress CSS 编码规范。
- 遵循 Calypso 的 CSS 规范。
- 使用 BEM 进行 类名 的定义。
- 为所有类名添加前缀。
WooCommerce 语法、标点符号和首字母大写指南
遵循语法、标点符号和风格指南有助于保持我们文档的一致性。 如果用户知道他们能得到什么以及在哪里找到他们需要的信息,他们的体验会更好。
基础
保持开放性。 有些人会阅读每一个字。 有些人会浏览和搜索,或者更喜欢视频。 帮助所有人。
保持重点。 在句子、段落和部分中,以最重要的信息开头。
保持简洁。 使用通俗易懂的语言和简短的句子。
保持一致性。 遵循我们的指南和风格提示。
保持具体性。 清晰地表达。 避免冗余。
指南
缩写和首字母缩略词
第一次出现时,完整地写出词语,并在括号中添加缩写或首字母缩略词。 在第二次和后续的出现中,使用简短的版本。
- 第一次使用:Payment Card Industry Data Security Standard (PCI-DSS)
- 第二次使用:PCI-DSS
如果缩写或首字母缩略词是广泛使用的,则直接使用它。 例如:API, FAQ, HTML, PHP, SQL, SSL。
主动语态
在主动语态中,句子的主语执行动作。 在被动语态中,句子的主语是被动接受动作。
- 主动:Jon 下载了他的扩展文件。
- 被动:扩展文件是由 Jon 下载的。
首字母大写
以下情况需要首字母大写:
- 博客文章和文档文章的标题:第一个单词。
- 文档标题 (h2):对于文档标题和子标题,使用句首大写 (而不是标题大写)。
- 产品名称:每个单词,除了介词和连词。
- 句子:第一个单词。
- 无序/项目符号列表 - 每个条目的第一个单词。
以下情况使用小写:
- "ecommerce" (而不是 "eCommerce")
- Email 地址 -
info@woocommerce.com - 网站 URL -
developer.woocommerce.com
缩写
谨慎使用。 缩写,例如 I'm 和 there's,可以使写作更具非正式和对话的风格,但如果内容正在被翻译,则可能不合适。 例如,有时在线翻译器会忽略 don't 中的 "not"。
表情符号
表情符号可以为您的内容添加微妙的情感和幽默,或者吸引视觉注意力。 很少且有目的地使用。
数字
在句子的开头,将数字写成文字。 对于所有其他情况,将数字 1 到 9 写成文字。 对于其他数字,使用数字。
- 将在六月发布十款产品。 不要:10 款产品将在六月发布。
- Lance 参加了马拉松比赛,并在他的年龄组中获得第三名。
- 我为建筑项目购买了五把锤子和 21 种类型的钉子。
- 酒吧里有 18 种啤酒。
对于超过三个数字的数字,使用逗号:41,500, 170,000, 1,000,000 或 1 百万。
货币
在指定美元时,使用货币代码,而不要只使用符号/标志。 整数金额不需要小数点和两位小数。
- USD $20
- CAD $19.99
- AUD $39.50
在描述其他货币时,使用符号/标志。
- €995
- ¥5,000
- £18.99
日期
完整地写出星期几和月份,使用以下格式:
- 星期一,2016年12月12日
小数
当一个数字难以转换为分数时,使用小数点,例如3.141 或 98.5 或 0.29。
分数
完整地写出分数,例如:one-fourth (四分之一)。
百分比
完整地写出单词 "percent"。 除非空间有限,例如在社交媒体上使用,否则不要使用 "%" 符号。
电话号码
使用连字符 "-" 连接数字,不要使用括号或句点。 对于所有国家/地区,请使用 国家代码。
- +1-555-867-5309
- +34-902-1899-00
范围和跨度
使用连字符 "-" 表示数字的范围,例如:20-30天。
温度
使用摄氏度符号 "°C" 和华氏度符号 "°F"。
- 27°C
- 98°F
时间
使用数字和 "am" 或 "pm",中间用空格分隔,不要使用句点。
- 7:00 am
- 7:30 pm
使用连字符 "-" 连接时间,表示 am 或 pm 之间的时段。 如果时间跨越 am 和 pm,则使用 "to"。
- 7:00-9:00 am 和 7:00 am to 10:30 pm
在描述可能涉及全球参与者的活动时,请指定时区。 Automattic 使用协调世界时 (Coordinated Universal Time, UTC)。
缩写美国时区:
- 华盛顿时间:EDT 或 EST
- 中部时间:CDT 或 CST
- 山区时间:MDT 或 MST
- 太平洋时间:PDT 或 PST
年份
缩写十年:
- 80年代和 90年代
- 1900年代和 1890年代
标点符号
连接符
连接符 "&" 仅在公司/品牌名称中使用。 不要用它代替 "and"。
- Ben & Jerry's
- Andre, Timo 和 Donny 去 Camp Nou 观看足球比赛。
引号
引号使单词变为所有格。 如果一个单词以 "s" 结尾且为单数,则添加一个 "s"。 如果一个单词以 "s" 结尾且为复数,则添加一个撇号。
- 同一个队友借用了 Sam 的自行车。
- 同一个队友借用了 Chris 的自行车。
- 员工藏起了办公室经理的笔。
以下是所有格:FAQ's questions, HE's weekly rotation。 以下是复数:FAQs 和 HEs。
冒号
使用冒号创建列表。
- Aaron 订购了三种甜甜圈:糖霜、巧克力和南瓜。
逗号
在列出项目时,使用逗号(也称为牛津逗号)。
- Jinny 喜欢向日葵、雏菊和牡丹。
在其他情况下,请使用常识。 大声朗读句子,并在需要清晰或停顿的地方使用逗号。
破折号和连字符
使用连字符 "-"(两侧没有空格)连接单词,或表示跨度或范围。
- first-time user (首次用户)
- Monday-Friday (周一至周五)
使用长破折号 "-"(两侧没有空格)表示日记或补充说明。
使用真正的长破折号,而不是连字符。
- 多元测试,这是我们新的专业版功能之一,可以帮助您发展业务。
- Austin 认为 Brad 偷了甜甜圈,但他是错的,是 Lain 偷的。
省略号
省略号 "..." 可以用来表示句子的未定义结尾,或者表示省略了单词(用方括号 [...] 表示)。 很少使用。
感叹号
很少使用感叹号,并且只使用一个。
感叹号的用法遵循与句号相同的规则,具体请参考“句号”部分。
句号
句号应该:
- 位于引号内
- 位于括号外,当括号内的内容是较大句子的一部分时
- 位于括号内,当括号内的内容可以独立存在时
示例
- Jake 说:“我度过了最棒的一天。”
- 她去了超市(也去了美甲店)。
- 我妈妈喜欢披萨和啤酒。(啤酒需要冰镇且颜色深。)
问号
问号的用法遵循与句号相同的规则,具体请参考“句号”部分。
引号
句号和逗号位于引号内。引号内的问号遵循逻辑:如果问号是引号的一部分,则位于引号内。如果您要提问,且问题以引号结尾,则问号位于引号外。
在引号内使用单引号。
- 谁唱着“All These Things That I've Done”?
- The Killers 乐队的 Brandon Flowers 说:“当我写 'I got soul, but I'm not a soldier' 时,我感到受到启发并充满灵感。”
分号
分号可以用来连接两个相关的短语。
- 他们的首张个人专辑在 20 个国家进入前 10 名;它在英国排名第一。
人物、地点和事物
公司名称和产品
使用公司名称和产品在官方网站上所写的名称。
- Pull&Bear
- UE Boom
将公司或产品称为 "it"(而不是 "they")。
- WooCommerce 是,而不是 WooCommerce 是。
文件扩展名
文件扩展名应全部大写,不带句点。为了表示复数,添加一个小写字母 "s"。
- HTML
- JPEG
特定文件的扩展名应为小写:
- dancingcat.gif
- SalesReport2016.pdf
- firethatcannon.mp3
姓名和职称
首次提到某人时,应包括他们的名和姓。后续提及可以使用名。
对职称、团队名称和部门名称进行大写处理。
- Happiness Engineers 或 HEs
- Team Apollo
- Legal
代词
根据情况使用 he/him/his 和 she/her/her。不要使用 "one" 作为代词。如果性别未知或指代一个群体,请使用 they/them/their。
引用
引用某人的话时,使用现在时。
- Brent Jamison 说:“我喜欢 WooCommerce 是免费且灵活的。”
学校
首次提到一所学校、学院或大学时,使用其完整的官方名称。在后续提及时,使用其更常见的简称。
- Georgia Institute of Technology, Georgia Tech
- Georgia State University, GSU
州、城市和国家
完整拼写所有城市和州名称。不要缩写城市名称。
首次提到时,写出 United States。在后续提及时,使用 U.S.。对于其他具有常用缩写的国家或联邦,也适用相同的规则,例如 European Union (EU) 和 United Kingdom (UK)。
网址和网站
将网站和网络出版物的名称首字母大写。不要使用斜体。
避免完整书写网址;在必要时省略 http://www。
俚语和行话
使用简洁的英语。文本应具有普遍的可理解性,并具有翻译的潜力。在需要时,简要定义技术术语。
文本格式化
使用斜体来表示书籍、电影或专辑的标题。
- Oren Klaff 的书籍 Pitch Anything 正在以 5.99 美元的价格出售。
避免:
- 使用下划线
- 混合使用斜体、粗体、大写字母和下划线
将文本左对齐,不要居中或右对齐。
句子之间留一个空格,不要留两个。
命名规范
PHP
WooCommerce 核心通常遵循 WordPress PHP 命名规范。
根据代码的位置,还存在一些额外的规范。
/src
/src 目录下的类遵循 PSR-4 标准。有关更多信息,请参阅 [/src] 的 README。
以下规范适用于此目录:
- 不需要类名前缀,因为此位置的所有类都位于
Automattic\WooCommerce命名空间中。 - 类名使用
CamelCase规范。 - 函数名使用
snake_case规范。 - 类文件名应与类名匹配。它们不需要
class-前缀。 - 命名空间应与目录结构匹配。
- Hook 前缀为
woocommerce_。 - Hook 使用
snake_case规范。
例如,src/Util/StringUtil.php 中定义的类应命名为 StringUtil,并位于 Automattic\WooCommerce\Util 命名空间中。
/includes
/includes 目录包含不遵循 PSR-4 标准的旧代码。有关更多信息,请参阅 [/includes] 的 README。
以下规范适用于此目录:
- 类名前缀为
WC_。 - 类名使用
Upper_Snake_Case规范。 - 函数名前缀为
wc_。 - 函数名使用
snake_case规范。 - Hook 前缀为
woocommerce_。 - Hook 使用
snake_case规范。
类名示例:
WC_Cache_HelperWC_Cart
函数名示例:
wc_get_product()wc_is_active_theme()
Hook 名示例(操作或过滤器):
woocommerce_after_checkout_validationwoocommerce_get_formatted_order_total
JS
WooCommerce 核心遵循 WordPress JS 命名规范。
与 PHP 类似,函数、类和 Hook 名称应添加前缀,但 JS 的规范略有不同。
- 全局类名前缀为
WC。从模块导出的类名不添加前缀。 - 类名使用
UpperCamelCase规范。 - 全局函数名前缀为
wc。从模块导出的函数名不添加前缀。 - 函数名使用
camelCase规范。 - Hook 名前缀为
woocommerce。 - Hook 使用
camelCase规范。
全局类名示例:
WCOrdersTable
全局函数名示例:
wcSettings()
Hook 名示例(操作或过滤器):
woocommerceTracksEventProperties
CSS and SASS
请参阅 CSS/Sass 命名规范。
如何为简单产品和可变产品添加自定义字段
在本教程中,您将学习如何为产品创建自定义字段并在您的商店中显示它。我们将一起设置插件的基本结构,并了解 WordPress 的命名约定和 WooCommerce 的钩子机制。最终,您将获得一个用于添加自定义字段的可用插件。
完整的插件代码 是基于 WordPress 6.2 和 WooCommerce 7.6.0 编写的。
前置条件
要完成本教程,您需要安装 WordPress,并激活 WooCommerce 插件。您还需要至少设置一个 简单产品,或者您可以 导入 WooCommerce 的示例产品。
设置插件
首先,让我们执行 创建插件的基本结构 的步骤。
首先,导航到您的 wp-content/plugins 文件夹,然后运行:
npx @wordpress/create-block -t @woocommerce/create-woo-extension woo-product-fields
然后,我们导航到新的文件夹并运行安装和构建命令:
cd woo-product-fields
npm install # 安装依赖
npm run build # 构建 JavaScript
WordPress 具有自己的类文件命名约定,该约定默认情况下不符合 PSR-4 标准。要了解更多关于命名约定的信息,请参阅 WP Handbook。我们将使用标准的 "class-my-classname.php" 格式,因此,让我们修改 composer.json 文件中的 autoload 配置为:
"autoload": {
"classmap": ["includes/", "includes/admin/"]
},
保存后,运行 dump-autoload 命令以生成类映射,在终端中运行:
composer dump-autoload -o
这将生成一个新的 vendor/composer/autoload_classmap.php 文件,其中包含 /includes/ 和 /includes/admin/ 文件夹中所有类的列表。每当我们添加、删除或移动类文件时,都需要重复此命令。
WooCommerce 钩子
我们的目标是为 WooCommerce 产品创建一个新的自定义文本字段,用于保存新的库存信息,以便在商店中显示。为此,我们需要修改 WooCommerce 后台管理区域中包含库存信息的区域。
WooCommerce 允许我们通过 钩子 将我们的代码添加到这些区域,钩子是 WordPress 扩展代码的标准方法。在 "库存" 部分,我们有以下可用的操作钩子:
对于我们的 WooCommerce 扩展,我们将使用 woocommerce_product_options_inventory_product_data 钩子,将我们的字段附加到该部分的末尾。
创建我们的类
让我们开始创建一个新的类,该类将包含字段的代码。 在 /includes/admin/ 文件夹中添加一个名为 class-product-fields.php 的新文件。 在类中,我们添加命名空间、如果有人尝试直接调用该文件则中止,以及一个 __construct 方法,该方法调用 hooks() 方法:
<?php
namespace WooProductField\Admin;
defined( 'ABSPATH' ) || exit;
class ProductFields {
public function __construct() {
$this->hooks();
}
private function hooks() {}
}
然后,在终端中运行 composer dump-autoload -o 命令以重新生成类映射。 完成后,我们将该类添加到 setup.php 的 __construct() 函数中,如下所示:
class Setup {
public function __construct() {
add_action( 'admin_enqueue_scripts', array( $this, 'register_scripts' ) );
new ProductFields();
}
}
添加自定义字段
在配置类并调用其方法后,我们可以创建一个函数来添加自定义字段。WooCommerce 提供了自己的 woocommerce_wp_text_input( $args ) 函数,我们可以在此处使用它。$args 是一个数组,允许我们设置文本输入的数据,我们将使用全局 $product_object 对象来访问存储的元数据。
public function add_field() {
global $product_object;
?>
<div class="inventory_new_stock_information options_group show_if_simple show_if_variable">
<?php woocommerce_wp_text_input(
array(
'id' => '_new_stock_information',
'label' => __( 'New Stock', 'woo_product_field' ),
'description' => __( 'Information shown in store', 'woo_product_field' ),
'desc_tip' => true,
'value' => $product_object->get_meta( '_new_stock_information' )
)
); ?>
</div>
<?php
}
让我们看一下数组中的参数。ID 将用作数据库中的 meta_key。标签和描述显示在数据部分,通过将 desc_tip 设置为 true,它将显示为悬停在信息图标上时的提示。最后一个参数 value 确保如果已经存储了值,则会显示该值。
对于 div 类,类名 show_if_simple 和 show_if_variable 将控制何时显示我们的部分。这与 JavaScript 代码相关联,该代码动态地隐藏/显示部分。例如,如果我们希望从可变产品中隐藏该部分,我们可以简单地删除 show_if_variable。
现在我们有了该字段,我们需要保存它。为此,我们可以钩入 woocommerce_process_product_meta,它接受两个参数:$post_id 和 $post:
public function save_field( $post_id, $post ) {
if ( isset( $_POST['_new_stock_information'] ) ) {
$product = wc_get_product( intval( $post_id ) );
$product->update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'] ) );
$product->save_meta_data();
}
}
此函数检查我们的新字段是否在 POST 数组中。如果存在,我们创建产品对象,更新我们的元数据并保存元数据。update_meta_data 函数将更新现有的元字段或添加新的元字段。由于我们正在向数据库插入数据,因此我们必须 清理我们的字段值。
为了使所有内容正常工作,我们添加以下钩子:
private function hooks() {
add_action( 'woocommerce_product_options_inventory_product_data', array( $this, 'add_field' ) );
add_action( 'woocommerce_process_product_meta', array( $this, 'save_field' ), 10, 2 );
}
现在,如果我们在产品屏幕上进行刷新,我们可以看到我们的新字段。
如果添加数据并保存产品,则新的元数据将插入到数据库中。
添加自定义字段到产品
此时,您已经拥有了一个可以保存产品自定义字段为产品元数据的插件。
在商店中显示字段
如果要在商店中显示新的字段,可以使用 WooCommerce 产品类的 get_meta() 方法:$product->get_meta( '_new_stock_information' )
让我们开始创建一个新的文件 /includes/class-product.php。您可能已经注意到,该文件位于 /admin/ 文件夹之外,因为此代码将在前端运行。因此,在设置类时,我们也会相应地调整命名空间:
<?php
namespace WooProductField;
defined( 'ABSPATH' ) || exit;
class Product {
public function __construct() {
$this->hooks();
}
private function hooks() { }
}
再次运行 composer dump-autoload -o 以更新我们的类映射。
如果您查看了插件的设置,您可能会注意到 /admin/setup.php 仅在 WordPress 后台运行时才会被调用。因此,为了调用我们的新类,我们将在 /woo-product-field.php 中直接添加它:
public function __construct() {
if ( is_admin() ) {
new Setup();
}
new WooProductField\Product();
}
对于将字段添加到前端,我们有几种选项。我们可以创建一个主题模板,但如果我们在使用与 WooCommerce 兼容的主题,并且不需要进行任何其他更改,那么一种快速的方法是使用钩子。如果我们查看 /woocommerce/includes/wc-template-hooks.php,我们可以看到所有现有的 woocommerce_single_product_summary 动作,该动作控制产品页面的顶部部分:
对于我们的插件,我们将在摘要之后添加新的库存信息,并使用 21 作为优先级:
private function hooks() {
add_action( 'woocommerce_single_product_summary', array( $this, 'add_stock_info' ), 21 );
}
在我们的函数中,我们使用 适当的转义函数 输出库存信息,在这种情况下,我建议使用 esc_html() 来强制使用纯文本。
public function add_stock_info() {
global $product;
?>
<p><?php echo esc_html( $product->get_meta( '_new_stock_information' ) ); ?> </p>
<?php
}
现在,如果刷新产品页面,我们的库存信息将显示在摘要下方:
太棒了!您已完成本教程,并且拥有一个可以添加新自定义字段并在商店中显示它的 WooCommerce 插件!🎉 我希望它向您展示了如何通过钩子轻松扩展 WooCommerce,并根据您或您的客户的商店需求进行定制!
以下是一个可选的任务,如果您对可变产品感兴趣。您可以稍后再回来查看。
如何处理可变产品?
上面的示例是使用一个简单产品进行的。但是,如果存在变体,例如一件有多种尺码的 T 恤,并且我们希望为每个变体存储不同的库存信息,该怎么办?WooCommerce 允许我们使用 可变产品类型 来实现这一点。
可变产品类型具有变体作为其子项。要为变体添加自定义字段,我们可以使用 woocommerce_variation_options_inventory 钩子,并使用 woocommerce_save_product_variation 进行保存。因此,让我们更新我们的 hooks() 方法,添加新的动作钩子,如下所示:
private function hooks() {
add_action( 'woocommerce_product_options_inventory_product_data', array( $this, 'add_field' ) );
add_action( 'woocommerce_process_product_meta', array( $this, 'save_field' ), 10, 2 );
add_action( 'woocommerce_variation_options_inventory', array( $this, 'add_variation_field' ), 10, 3 );
add_action( 'woocommerce_save_product_variation', array( $this, 'save_variation_field' ), 10, 2 );
}
配置方式与简单产品非常相似,主要区别在于我们需要使用 $loop ID,该 ID 用于区分不同的变体,并且我们将使用 wrapper_class 将其显示为全宽的文本输入框:
public function add_variation_field( $loop, $variation_data, $variation ) {
$variation_product = wc_get_product( $variation->ID );
woocommerce_wp_text_input(
array(
'id' => '_new_stock_information' . '[' . $loop . ']',
'label' => __( 'New Stock Information', 'woo_product_field' ),
'wrapper_class' => 'form-row form-row-full',
'value' => $variation_product->get_meta( '_new_stock_information' )
)
);
}
用于保存的代码如下:
public function save_variation_field( $variation_id, $i ) {
if ( isset( $_POST['_new_stock_information'][$i] ) ) {
$variation_product = wc_get_product( $variation_id );
$variation_product->update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'][$i] ) );
$variation_product->save_meta_data();
}
}
现在,我们有一个新的变体字段,用于存储新的库存信息。 如果您看不到新的字段,请确保为该变体启用“管理库存”,方法是在变体详情中选中复选框。
在前端商店显示变体的方式对于可变产品来说略有不同,因为只有当客户进行选择时,网页上的某些内容才会更新。 这超出了本教程的范围,但如果您感兴趣,可以查看 /woocommerce/assets/js/frontend/add-to-cart-variation.js,了解 WooCommerce 的实现方式。
如何查找钩子?
每个人都有自己偏好的方法,但对我来说,最快的方法是在 WooCommerce 插件的代码中查找。每个数据部分的 code 可以在 /woocommerce/includes/admin/meta-boxes/views 目录下找到。要查看如何处理 库存 部分,请查看 html-product-data-inventory.php 文件,而要查看 变体 的处理方式,请查看 html-variation-admin.php 文件。
使用 WooCommerce CRUD 对象进行开发
CRUD 是对数据库或资源上可以执行的四个基本操作的缩写:创建、读取、更新、删除。
WooCommerce 3.0 引入了 CRUD 对象,用于处理 WooCommerce 数据。在您的代码中,尽可能使用这些对象,而不是直接更新元数据或使用 WordPress 文章对象。
每个对象都包含一个用于控制其数据的结构化数据(属性),以及每个属性的 getter 和 setter,以及一个用于与数据存储交互的保存/删除方法。 数据存储负责实际的保存/读取操作。 对象本身不需要知道数据存储在哪里。
CRUD 的优势
- 结构: 每个对象都有预定义的结构,并保持其数据的有效性。
- 控制: 我们控制数据流,以及所需的任何验证,因此我们知道何时发生更改。
- 开发简便性: 作为开发人员,您无需了解正在处理的数据的内部结构,只需要知道属性名称。
- 抽象: 数据可以移动到其他地方,例如自定义表,而不会影响现有代码。
- 统一: 我们可以使用相同的代码来更新管理后台中的内容,以及在 REST API 和 CLI 中,一切都统一。
- 简化代码: 减少更新对象的程序化代码,从而降低出现故障的可能性,并增加单元测试覆盖率。
CRUD 对象结构
[WC_Data](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/abstracts/abstract-wc-data.php) 类是 CRUD 对象的基本实现,所有 CRUD 对象都继承自它。 需要注意的最重要的属性是 $data,它是一个数组,包含每个对象支持的属性,以及 $id,它是对象的 ID。
优惠券对象类 是一个很好的例子,它展示了如何扩展 WC_Data 并为所有属性添加 CRUD 函数。
数据
$data 存储属性名称和默认值:
/**
* 数据数组,包含默认值。
* @since 3.0.0
* @var array
*/
protected $data = array(
'code' => '',
'amount' => 0,
'date_created' => '',
'date_modified' => '',
'discount_type' => 'fixed_cart',
'description' => '',
'date_expires' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => 0,
'usage_limit_per_user' => 0,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'email_restrictions' => array(),
'used_by' => array(),
);
获取器和设置器
数组中的每个键(属性)都有一个对应的获取器和设置器,例如 set_used_by() 和 get_used_by()。 $data 本身是私有的,因此必须使用获取器和设置器来访问数据。
示例获取器:
/**
* 获取所有使用当前优惠券的用户记录。
* @since 3.0.0
* @param string $context
* @return array
*/
public function get_used_by( $context = 'view' ) {
return $this->get_prop( 'used_by', $context );
}
示例设置器:
/**
* 设置哪些用户已经使用了此优惠券。
* @since 3.0.0
* @param array $used_by
* @throws WC_Data_Exception
*/
public function set_used_by( $used_by ) {
$this->set_prop( 'used_by', array_filter( $used_by ) );
}
set_prop 和 get_prop 是 WC_Data 的一部分。 它们应用各种过滤器(基于上下文)并处理更改,因此我们可以高效地仅保存已更改的属性,而不是所有属性。
关于 $context 的说明:当获取用于前端或显示的的数据时,使用 view 上下文。 这会对数据应用过滤器,以便扩展可以动态更改值。 当在后端显示用于编辑的值时,应使用 edit 上下文,并且用于将数据保存到数据库时也应使用 edit 上下文。 使用 edit 上下文不会对数据应用任何过滤器。
构造函数
CRUD 对象的构造函数用于从数据库中读取数据。 实际读取操作不是由 CRUD 类本身完成,而是由其数据存储层完成。
示例:
/**
* 优惠券构造函数。加载优惠券数据。
* @param mixed $data 优惠券数据,对象、ID 或代码。
*/
public function __construct( $data = '' ) {
parent::__construct( $data );
if ( $data instanceof WC_Coupon ) {
$this->set_id( absint( $data->get_id() ) );
} elseif ( is_numeric( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
$this->set_id( $data );
} elseif ( ! empty( $data ) ) {
$this->set_id( wc_get_coupon_id_by_code( $data ) );
$this->set_code( $data );
} else {
$this->set_object_read( true );
}
$this->data_store = WC_Data_Store::load( 'coupon' );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
}
注意,它根据传递给对象的 data 设置 ID,然后调用数据存储层以从数据库中检索数据。 一旦数据通过数据存储层读取,或者如果未设置 ID,则 $this->set_object_read( true ); 被设置,以便数据存储层和 CRUD 对象知道它已读取。 一旦设置了此标志,更改就会被跟踪。
保存和删除
save 和 delete 方法在 CRUD 子类中是可选的,因为 WC_Data 父类可以处理它们。 当调用 save 时,数据存储层用于将数据存储到数据库。 delete 从数据库中移除对象。 必须调用 save 方法才能使更改永久生效,否则这些更改将被丢弃。
WC_Data 中的 save 方法如下所示:
/**
* `save` 方法应该根据对象是否存在来创建或更新。
*
* @since 2.6.0
* @return int
*/
public function save() {
if ( $this->data_store ) {
// 在保存到数据库之前触发操作。 允许您在保存之前调整对象属性。
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
return $this->get_id();
}
}
根据对象是否已经具有 ID,会使用更新/创建操作。 ID 将在创建后设置。
delete 方法如下所示:
/**
* 删除对象,将 ID 设置为 0,并返回结果。
*
* @since 2.6.0
* @param bool $force_delete
* @return bool 结果
*/
public function delete( $force_delete = false ) {
if ( $this->data_store ) {
$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
$this->set_id( 0 );
return true;
}
return false;
}
CRUD 使用示例
创建一个新的简单产品
$product = new WC_Product_Simple();
$product->set_name( 'My Product' );
$product->set_slug( 'myproduct' );
$product->set_description( 'A new simple product' );
$product->set_regular_price( '9.50' );
$product->save();
$product_id = $product->get_id();
更新现有优惠券
$coupon = new WC_Coupon( $coupon_id );
$coupon->set_discount_type( 'percent' );
$coupon->set_amount( 25.00 );
$coupon->save();
获取客户信息
$customer = new WC_Customer( $user_id );
$email = $customer->get_email();
$address = $customer->get_billing_address();
$name = $customer->get_first_name() . ' ' . $customer->get_last_name();
优惠券管理
本页面用于管理优惠券。您可以查看、创建、编辑和删除优惠券。
- 新增优惠券:点击“新增”按钮,可以创建新的优惠券。
- 编辑优惠券:点击优惠券列表中的“编辑”按钮,可以修改现有优惠券的设置。
- 删除优惠券:点击优惠券列表中的“删除”按钮,可以删除优惠券。
优惠券详情
显示单个优惠券的详细信息,包括:
- 名称 (Name):优惠券的名称。
- 折扣 (Discount):优惠券的折扣类型和金额。
- 使用 (Use):优惠券的使用限制,例如最小订单金额、使用次数等。
- 有效期 (Expiration Date):优惠券的有效期。
- 其他设置 (Other Settings):其他自定义设置。
优惠券列表
显示所有优惠券的列表,包括:
- 名称 (Name):优惠券的名称。
- 折扣 (Discount):优惠券的折扣类型和金额。
- 使用次数 (Count):优惠券已使用的次数。
- 状态 (Status):优惠券的状态,例如“有效”、“已过期”、“已禁用”。
批量操作
您可以对多个优惠券进行批量操作,例如:
- 删除 (Delete):删除选中的优惠券。
- 更新 (Updating):更新选中的优惠券的状态。
导入/导出
您可以将优惠券数据从一个系统导入到另一个系统,或者将优惠券数据导出为文件。
- 导入 (Import):从文件导入优惠券数据。
- 导出 (Export):将优惠券数据导出为文件。
优惠券代码
以下是一些常用的优惠券代码示例:
%s:占位符,表示用户可以自定义的文本。{name}:占位符,表示客户的名称。
邮件通知
当客户使用优惠券时,您可以发送电子邮件通知。
- 邮件 (Mail):发送电子邮件通知。
- 收件人 (Address):收件人的电子邮件地址。
- 主题 (Subject):电子邮件的主题。
- 正文 (Body):电子邮件的正文内容。
账单 (Billing)
显示与优惠券相关的账单信息。
- 金额 (Amount):优惠券的金额。
- 百分比 (Percent):优惠券的百分比折扣。
- 类型 (Type):优惠券的类型。
常见问题
- 如何创建新的优惠券? 点击“新增”按钮,填写优惠券的详细信息,然后点击“保存”按钮。
- 如何修改现有优惠券? 点击优惠券列表中的“编辑”按钮,修改优惠券的设置,然后点击“保存”按钮。
- 如何删除优惠券? 点击优惠券列表中的“删除”按钮,确认删除操作。
- 如何使用优惠券? 在结账时,输入优惠券代码,系统会自动应用折扣。
- 优惠券的有效期是什么? 优惠券的有效期由您在创建优惠券时设置。
- 如何查看优惠券的使用情况? 在优惠券详情页面,您可以查看优惠券的使用次数和状态。
- 如何导出优惠券数据? 点击“导出”按钮,选择导出的文件格式,然后点击“下载”按钮。
- 如何导入优惠券数据? 点击“导入”按钮,选择要导入的文件,然后点击“上传”按钮。
错误信息
Invalid coupon code.:优惠券代码无效。Coupon has expired.:优惠券已过期。Coupon has already been used.:优惠券已使用。Minimum order amount not met.:未达到最小订单金额。Coupon cannot be applied to this product.:该优惠券无法应用于该商品。Error updating coupon.:更新优惠券时出错。Error deleting coupon.:删除优惠券时出错。Error importing coupon data.:导入优惠券数据时出错。Error exporting coupon data.:导出优惠券数据时出错。
提示
- 您可以使用搜索框快速查找优惠券。
- 您可以使用分页功能浏览优惠券列表。
- 您可以使用排序功能对优惠券列表进行排序。
- 您可以使用过滤器功能筛选优惠券列表。
- 如果您在使用优惠券时遇到问题,请联系客服。
- 请定期检查和更新您的优惠券,以确保其有效性。
- 您可以创建自定义的优惠券代码,以满足您的特定需求。
- 您可以
数据存储基础
在为 WordPress 和 WooCommerce 开发时,重要的是要考虑数据的性质和持久性。这将帮助您决定最佳的存储方式。以下是一个简要的介绍:
瞬态
如果数据可能并不总是存在(即,数据会过期),请使用 瞬态。瞬态是一种简单且标准化的方法,用于在数据库中临时存储缓存数据,通过为其指定自定义名称和过期时间,在过期后自动删除。
WP 缓存
如果数据是持久的,但并不总是存在,请考虑使用 WP 缓存。WP 缓存函数允许您缓存需要大量计算才能重新生成的复杂数据,例如复杂的查询结果。
wp_options 表
如果数据是持久的并且始终存在,请考虑使用 wp_options 表。Options API 是一种简单且标准化的方法,用于在 WordPress 数据库的 wp_options 表中存储数据。
帖子类型
如果数据类型是具有 n 个单位的实体,请考虑使用 帖子类型。帖子类型是存储方式相同的内容的“类型”,但在代码和 UI 中易于区分。
分类法
如果数据是一种对实体进行排序/分类的手段,请考虑使用 分类法。分类法是一种将事物分组的方法。
日志
日志应使用 WC_Logger 类写入文件。这是一种简单且标准化的记录事件和错误的方法,用于调试。
请记住,最佳的数据存储方法取决于数据的性质以及它将在您的应用程序中如何使用。
如何管理 WooCommerce 数据存储
简介
数据存储类充当 WooCommerce 的数据 CRUD 类(WC_Product, WC_Order, WC_Customer 等)与数据库层之间的桥梁。 通过将数据库逻辑与数据分离,WooCommerce 变得更加灵活。 随 WooCommerce 核心提供的、基于 WordPress 的自定义文章系统和一些自定义表的的数据存储,可以被替换为不同的数据库结构、类型,甚至可以由外部 API 提供。
本指南将介绍数据存储类的结构,如何创建新的数据存储,如何替换核心数据存储,以及如何在您自己的代码中调用数据存储。
本指南中的示例将查看 WC_Coupon CRUD 数据类,以及 WC_Coupon_Data_Store_CPT,这是一个使用 WordPress 自定义文章类型的优惠券数据存储的实现。 这是 WooCommerce 当前存储优惠券的方式。
在使用数据存储时,需要了解 WC_Coupon 或任何其他 CRUD 数据类包含哪些属性(properties)。 这些属性在每个类的 data 数组中定义。
结构
每个 CRUD 对象的数据库存储都应该实现 WC_Object_Data_Store_Interface 界面。
WC_Object_Data_Store_Interface 包含以下方法:
createreadupdatedeleteread_metadelete_metaadd_metaupdate_meta
create、read、update 和 delete 方法应该处理您属性的 CRUD 逻辑:
create应该在数据库中创建一个新的条目。 示例:创建优惠券。read应该从数据库中查询单个条目,并根据响应设置属性。 示例:读取优惠券。update应该对现有条目进行更改。 示例:更新或编辑优惠券。delete应该从数据库中移除一个条目。 示例:删除优惠券。
所有数据库存储都必须实现对这些方法的处理。
除了处理您的属性之外,还可以传递其他自定义数据。 这被认为是“元数据”。 例如,优惠券可以具有插件提供的自定义数据。
read_meta、delete_meta、add_meta 和 update_meta 方法应该被定义,以便可以从正确的来源读取和管理元数据。 在我们的 WooCommerce 核心类中,我们在 WC_Data_Store_WP 中定义它们,然后为所有数据库存储使用相同的代码。 它们都使用 WordPress 的元数据系统。 如果元数据应该来自不同的来源,您可以重新定义这些方法。
您的数据库存储还可以实现其他方法来替换直接查询。 例如,优惠券数据库存储具有一个公共的 get_usage_by_user_id 方法。 数据库存储应该始终定义和实现一个界面,用于它们期望的方法,以便其他开发者知道他们需要编写哪些方法。 换句话说,除了 WC_Object_Data_Store_Interface 界面之外,WC_Coupon_Data_Store_CPT 还实现了 WC_Coupon_Data_Store_Interface。
替换数据存储
让我们看看如何用 WC_Coupon_Data_Store_Custom_Table 类替换 WC_Coupon_Data_Store_CPT 类。 我们的示例将仅提供占位函数,而不是完整的解决方案。 假设我们希望将优惠券存储在名为 wc_coupons 的表中,该表具有以下列:
id, code, amount, date_created, date_modified, discount_type, description, date_expires, usage_count,individual_use, product_ids, excluded_product_ids, usage_limit, usage_limit_per_user, limit_usage_to_x_items, free_shipping, product_categories, excluded_product_categories, exclude_sale_items, minimum_amount, maximum_amount, email_restrictions, used_by
这些列名与属性名一一对应。
首先,我们需要创建一个新的数据存储类来包含我们的逻辑:
/**
* WC 优惠券数据存储:自定义表。
*/
class WC_Coupon_Data_Store_Custom_Table extends WC_Data_Store_WP implements WC_Coupon_Data_Store_Interface, WC_Object_Data_Store_Interface {
}
请注意,我们实现了主要的 WC_Object_Data_Store_Interface 接口以及 WC_Coupon_Data_Store_Interface 接口。 它们共同代表了我们需要提供逻辑的所有方法。
然后,我们将定义这些属性的 CRUD 处理:
/**
* 用于在数据库中创建新优惠券的方法。
*
* @param WC_Coupon
*/
public function create( &$coupon ) {
$coupon->set_date_created( current_time( 'timestamp' ) );
/**
* 这是插入新优惠券的代码所在的位置。
* 将使用 getter 构建查询:$coupon->get_code(), $coupon->get_description() 等。
* 在 INSERT 操作之后,我们希望将新的 ID 传递给优惠券对象。
*/
$coupon->set_id( $coupon_id );
// 在创建或更新条目后,我们需要同时触发 'meta' 的保存。
$coupon->save_meta_data();
// `apply_changes` 方法告诉对象,当前对象反映了数据库,并且两个对象之间不存在“更改”。
$coupon->apply_changes();
// 为了方便插件与您的数据存储进行交互,建议在操作完成后提供相同的钩子。
do_action( 'woocommerce_new_coupon', $coupon_id );
}
/**
* 用于读取优惠券的方法。
*
* @param WC_Coupon
*/
public function read( &$coupon ) {
$coupon->set_defaults();
// `Read` 方法应该检查是否为有效的优惠券,
// 如果不是,则抛出 "Invalid coupon" 异常。
// 对于有效的优惠券,将 `$data` 设置为包含数据库结果。
// 所有属性都应使用 `set_props` 方法,并使用来自数据库的输出进行设置。这会将 CRUD 数据对象进行“填充”。
$coupon_id = $coupon->get_id();
$coupon->set_props( array(
'code' => $data->code,
'description' => $data->description,
// ..
) );
// 此外,我们还需要将元数据读取到对象中。
$coupon->read_meta_data();
// 此标志指示对象是否已填充。如果此标志为 false,则表示数据库未正确设置对象。
$coupon->set_object_read( true );
do_action( 'woocommerce_coupon_loaded', $coupon );
}
/**
* 更新数据库中的优惠券。
*
* @param WC_Coupon
*/
public function update( &$coupon ) {
// 更新优惠券查询,使用 getter 方法。
$coupon->save_meta_data();
$coupon->apply_changes();
do_action( 'woocommerce_update_coupon', $coupon->get_id() );
}
/**
* 从数据库中删除优惠券。
*
* @param WC_Coupon
* @param array $args 传递给删除方法的参数数组。
*/
public function delete( &$coupon, $args = array() ) {
// WordPress 和 WooCommerce 中的许多对象
// 支持“回收站”的概念。这通常是一个标志,用于将对象
// 移动到“回收站”。由于优惠券支持回收站,因此您的层也应该支持。
// 如果实际发生删除,则将优惠券 ID 设置为 0。
$args = wp_parse_args( $args, array(
'force_delete' => false,
) );
$id = $coupon->get_id();
if ( $args['force_delete'] ) {
// 删除查询
$coupon->set_id( 0 );
do_action( 'woocommerce_delete_coupon', $id );
} else {
// 回收站查询
do_action( 'woocommerce_trash_coupon', $id );
}
}
我们正在扩展 WC_Data_Store_WP,因此我们的类将继续使用 WordPress 的元数据系统。
如“结构”部分中所述,我们负责实现 WC_Coupon_Data_Store_Interface 定义的方法。每个接口描述了它接受的方法和参数,以及您的函数应该执行的操作。
一个优惠券的替换方法如下所示:
/**
* 增加当前优惠券的使用次数。
*
* @param WC_Coupon
* @param string $used_by 用户 ID 或账单电子邮件。
*/
public function increase_usage_count( &$coupon, $used_by = '' ) {
}
/**
* 减少当前优惠券的使用次数。
*
* @param WC_Coupon
* @param string $used_by 用户 ID 或账单电子邮件。
*/
public function decrease_usage_count( &$coupon, $used_by = '' ) {
}
/**
* 获取特定用户 ID 的优惠券使用次数。
*
* @param WC_Coupon
* @param id $user_id
* @return int
*/
public function get_usage_by_user_id( &$coupon, $user_id ) {
}
/**
* 返回特定 ID 的优惠券代码。
* @param int $id
* @return string 优惠券代码
*/
public function get_code_by_id( $id ) {
}
/**
- 返回指定优惠券代码的 ID 数组。
- 可以返回多个 ID 以检查是否存在。
- @param string $code
- @return array ID 数组。 */ public function get_ids_by_code( $code ) {
}
一旦所有的数据存储方法都定义完成,并且逻辑编写完毕,我们需要告诉 WooCommerce 加载我们的新类,而不是内置的类。 这通过使用 `woocommerce_data_stores` 过滤器来实现。 一个数据存储别名数组映射到默认的 WooCommerce 类。 示例:
```php
'coupon' => 'WC_Coupon_Data_Store_CPT',
'customer' => 'WC_Customer_Data_Store',
'customer-download' => 'WC_Customer_Download_Data_Store',
'customer-session' => 'WC_Customer_Data_Store_Session',
'order' => 'WC_Order_Data_Store_CPT',
'order-refund' => 'WC_Order_Refund_Data_Store_CPT',
'order-item' => 'WC_Order_Item_Data_Store',
'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store',
'order-item-fee' => 'WC_Order_Item_Fee_Data_Store',
'order-item-product' => 'WC_Order_Item_Product_Data_Store',
'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store',
'order-item-tax' => 'WC_Order_Item_Tax_Data_Store',
'payment-token' => 'WC_Payment_Token_Data_Store',
'product' => 'WC_Product_Data_Store_CPT',
'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT',
'product-variable' => 'WC_Product_Variable_Data_Store_CPT',
'product-variation' => 'WC_Product_Variation_Data_Store_CPT',
'shipping-zone' => 'WC_Shipping_Zone_Data_Store',
我们希望专门针对优惠券数据存储,因此我们可以这样做:
function myplugin_set_wc_coupon_data_store( $stores ) {
$stores['coupon'] = 'WC_Coupon_Data_Store_Custom_Table';
return $stores;
}
add_filter( 'woocommerce_data_stores', 'myplugin_set_wc_coupon_data_store' );
然后,WooCommerce 核心将加载我们的类,而不是 WC_Coupon_Data_Store_CPT。
创建新的数据存储
定义新的产品类型
你的扩展是否创建了一种新的产品类型? 每一个产品类型都有一个数据存储,除了父产品的数据存储之外。 父存储负责处理共享的属性,例如名称或描述,而子存储负责处理更具体的数据。
例如,外部产品数据存储负责处理“按钮文本”和“外部 URL”。 变量数据存储负责父产品与其变体之间的关系。
请查看 此教程,以获取有关此过程的更多信息。
用于自定义数据的存储
如果你的扩展引入了新的数据库表、新的自定义文章类型,或者某种与产品、订单等无关的新数据形式,那么你应该实现你自己的数据存储。
你的数据存储仍然应该实现 WC_Object_Data_Store_Interface 接口,并提供标准的 CRUD 函数。 你的数据存储应该是与你的数据交互的主要入口点,因此任何其他查询或操作也应该有相应的方法。
配送区域数据存储 是一个很好的例子,它展示了如何使用自定义表创建一个“简单”的数据存储。 优惠券的代码是一个很好的例子,展示了如何使用自定义文章类型的数据存储。
要注册你的数据存储,你只需要将其添加到 woocommerce_data_stores 过滤器中:
function myplugin_set_my_custom_data_store( $stores ) {
$stores['mycustomdata'] = 'WC_My_Custom_Data_Store';
return $stores;
}
add_filter( 'woocommerce_data_stores', 'myplugin_set_my_custom_data_store' );
然后,你可以像加载其他 WooCommerce 数据存储一样加载你的数据存储。
调用数据存储
调用数据存储就像使用静态的 WC_Data_Store::load() 方法一样简单:
// 加载配送区域数据存储。
$data_store = WC_Data_Store::load( 'shipping-zone' );
// 获取配送区域 ID 为 4 的配送方法数量。
$num_of_methods = $data_store->get_method_count( 4 );
你也可以链式调用方法:
// 获取配送区域 ID 为 4 的配送方法数量。
$num_of_methods = WC_Data_Store::load( 'shipping-zone' )->get_method_count( 4 );
::load() 方法适用于注册到 woocommerce_data_stores 的任何数据存储,因此你可以加载你的自定义数据存储:
$data_store = WC_Data_Store::load( 'mycustomdata' );
数据存储的限制和 WP 管理员
目前,一些 WooCommerce 界面仍然依赖于 WordPress 来列出对象。例如,优惠券和产品。
如果您通过数据存储进行数据替换,那么现有用户界面的一些部分可能会出现故障。例如,当使用 type 过滤器时,优惠券列表可能会出现问题。此过滤器使用元数据,然后将其传递给 WordPress,WordPress 使用 WP_Query 类执行查询。WP_Query 类无法处理位于常规元数据表之外的数据(参考 #19937)。为了解决这个问题,需要逐步淘汰 WP_Query 的使用,并用自定义的查询类和函数进行替换。
WooCommerce 日志记录
WooCommerce 拥有一个强大的日志记录系统,可用于在开发期间进行调试,在生产环境中捕获错误,甚至在发生特定事件时发送通知。 默认情况下,WooCommerce 使用此日志记录器来记录可能有助于解决商店问题的错误、警告和其他通知。 许多 WooCommerce 扩展也使用此日志记录器来实现类似的目的。
查看日志
您可以通过访问 WooCommerce > 状态 > 日志 来查看日志记录器创建的条目。 日志查看界面取决于配置的日志存储方法(请参阅下面的“配置日志记录器”部分)。
文件系统
使用默认的文件系统存储方法,您首先会看到现有日志文件的列表:

日志文件的名称基于其包含条目的来源(即扩展或 WooCommerce 代码库的一部分),以及创建条目的日期。 在此文件浏览视图中,您可以以不同的方式对文件进行排序,还可以对其进行过滤,仅显示来自特定来源的文件。 单击文件将进入单个文件视图,您可以在其中查看实际的日志条目:

单击文件中的行号以突出显示该行。 这也可以用于从其他位置链接到文件中的特定行。
从文件浏览器视图,您可以对日志文件列表进行排序和过滤,然后在这些文件的内容中搜索字符串:

单击搜索结果中的行号将带您到单个文件视图中的该行。
数据库
使用数据库存储方法,您将看到日志条目的列表,从最近的条目开始:

这些条目可以按时间戳、级别和来源进行排序,也可以进行过滤,仅显示特定来源或最小级别。 您还可以搜索日志条目消息字段中的字符串。
配置日志记录器
从 WooCommerce > 状态 > 日志 屏幕上的“日志”屏幕,单击“设置”链接以进行配置更改:

日志记录器
取消此处的复选框以关闭所有日志记录。 在大多数情况下,不建议这样做,因为日志记录可以提供有关您网站上正在发生情况的宝贵信息!
日志存储
默认情况下,WooCommerce 提供了两种不同的日志存储方法:
- 文件系统 - 日志条目记录到文件中。 文件通过日志条目的
source值(请参阅下面的“添加日志”部分)以及当前日期进行区分。 这些文件存储在站点的uploads目录下的wc-logs子目录中。 可以使用woocommerce_log_directory过滤器钩子定义自定义目录。 日志文件的大小可以达到 5MB,超过此大小后,日志文件将进行轮换。 - 数据库 - 日志条目记录到数据库中的
{$wpdb->prefix}woocommerce_log表中。
如果您更改此设置,并且已经存在一些日志条目,则这些条目将不会迁移到其他存储方法,但也不会被删除。
保留期限
日志记录器会定期检查并删除超过此时间段的旧日志,以节省空间。 如果日志条目存储在文件系统中,则超出保留期限的整个日志文件将被删除;而对于数据库存储,则会删除单个日志条目。
级别阈值
每个日志条目都有一个严重性级别(请参阅下面的“添加日志”部分)。 此设置定义一个最小严重性级别,任何生成且严重性级别低于或等于此最小级别的日志条目将不会被记录。 请谨慎使用此设置!
如果此设置设置为“无”,则表示所有日志条目都将被记录,无论其严重性级别如何。
添加日志
日志是通过 WC_Logger 类的各种方法添加的。 可以使用 wc_get_logger() 函数访问类实例。 添加日志条目的基本方法是 [WC_Logger::log( $level, $message, $context )](https://woocommerce.github.io/code-reference/classes/WC-Logger.html#method_log)。 此外,还提供了每个日志严重性级别的快捷方法,例如 WC_Logger::warning( $message, $context )。 建议使用快捷方法而不是通用的 log 方法。
级别
日志有八个不同的严重性级别:
emergencyalertcriticalerrorwarningnoticeinfodebug
除了为网站所有者提供有关日志条目的重要性的上下文信息外,这些级别还允许对日志进行过滤。 如果您只想记录严重性级别为 error 及以上的日志条目,可以在“日志设置”屏幕上设置阈值(请参阅上面的“配置日志记录器”)。
请注意,此阈值适用于所有日志,无论使用哪种日志处理程序。 例如,WC_Log_Handler_Email 类具有自己的阈值设置,但它不如全局阈值重要。
信息
信息是日志条目的主要内容。 确保其内容易于任何可能查看日志的人理解!
上下文
Context 参数旨在用于存储与日志条目相关的附加结构化数据。例如,在关于订单的日志条目中,您可能希望包含相关订单对象的 内容。当日志记录器 生成 一个条目时,Context 参数中的数据会转换为 JSON 格式后再进行存储。因此,如果您想添加多个 Context 数据,每个数据都应该作为 Context 数组中的一个单独的键进行添加。
有两个特定的键可以添加到 Context 数组中,它们会触发特殊的行为:
source
建议每个日志条目都包含一个 source 值在 Context 参数中。source 的目的是提供关于日志是在应用程序或代码库的哪个位置 生成 的 上下文 信息,并且可以用于过滤日志条目。
如果未指定 source,日志记录器会根据 生成 日志条目的插件或文件 生成 一个 source 值。
backtrace
将 Context 参数中的 backtrace 键设置为 true 会导致日志记录器 生成 一个 backtrace(即堆栈跟踪),该 backtrace 以数组格式存储,并将其包含在 Context 中,替换 true 值。这对于与 错误 相关的日志特别有用,这样您就可以看到导致 生成 该日志条目的代码。

完整示例
wc_get_logger()->info(
'It is time for lunch.',
array(
'source' => 'your_stomach',
'backtrace' => true,
'previous_meal' => $elapsed_time_since_breakfast,
'lunch_options' => array( 'fridge leftovers', 'bahn mi', 'tacos', 'pupusas' ),
)
);
日志记录的最佳实践
何时使用日志记录
- 用于解决意外问题:
- 从
API接收到意外的值或错误。 - 系统中的数据不正确或已损坏。
- 应用程序处于意外或损坏的状态。
- 从
- 用于记录过程的审计日志:
- 未在其他地方存储的事务
详情,例如订单备注(但可能应该存储?)。 - 数据导入或导出的
结果。 - 重要的
设置被更改。 - 自动化过程更改或删除数据。
- 未在其他地方存储的事务
何时不使用日志记录
- 用于告知开发人员他们正在错误地使用某个方法或
API。这可能会导致大量的无用日志条目,尤其是在它会在每个网页请求时触发的情况下。 最好通过错误或异常(例如wc_doing_it_wrong())提供即时反馈。
最佳实践
- 与其直接使用
WC_Logger的log()方法,最好使用专门针对日志级别的包装方法,例如info()或error()。 - 编写一个完整、连贯的句子作为日志信息。 这将使其对不熟悉代码库的人更有用。
- 日志信息不应是可翻译的。 保持信息以英文书写,可以更轻松地根据信息内容搜索解决方案,并且也便于任何进行故障排除的人理解正在发生的情况,因为他们可能使用的语言与网站所有者使用的语言不同。
- 理想情况下,每个日志条目的信息应该是一行(即,信息字符串中不应包含换行符)。 额外的行或额外数据应放在
context数组中。 - 避免在信息字符串中输出结构化数据。 将其放在
context数组中的键中。 日志记录器将负责将其转换为 JSON 格式,并在日志查看器中使其易于阅读。 - 如果需要包含堆栈跟踪,请让日志记录器为您生成它。
- 为正在使用的组件或系统选择一个来源,并在每次调用日志记录时使用它。 这将使查找与该组件相关的日志条目更容易,并将其与其他不相关的日志条目过滤掉。
- 考虑在循环过程之后添加一个日志条目,其中包含循环的聚合结果,而不是在循环中的每个条目时添加单独的条目。
自定义日志记录器
日志记录器类
可以通过 woocommerce_logging_class 过滤器钩子,用另一个类替换 WC_Logger 类。 替代类必须实现 WC_Logger_Interface,否则将不会使用。 通常,最好创建自定义日志处理程序(见下文),而不是直接覆盖日志记录器类。
日志处理程序
在 WooCommerce 中,日志处理程序是一个 PHP 类,它接收原始日志数据并将其转换为可以存储或分发的日志条目。 WooCommerce 提供了四种不同的日志处理程序类:
Automattic\\WooCommerce\\Internal\\Admin\\Logging\\LogHandlerFileV2: 这是一个默认的处理程序,代表“文件系统”日志存储方法。 它将日志条目记录到文件中。WC_Log_Handler_File: 这是一个旧的默认处理程序,也用于将日志条目记录到文件中。 可能会在未来被弃用,并且不建议使用此类或对其进行扩展。WC_Log_Handler_DB: 此处理程序代表“数据库”日志存储方法。 它将日志条目记录到数据库中。WC_Log_Handler_Email: 此处理程序不存储日志条目,而是将其作为电子邮件发送。 电子邮件发送到站点的管理员邮箱。 此处理程序有一些 限制。
更改或添加处理程序
要从文件处理程序切换到数据库处理程序,您可以简单地更新“日志设置”屏幕上的选项。 但是,在某些情况下,您可能希望拥有多个日志处理程序,并且/或您可能希望修改处理程序的设置。 例如,您可能希望将大多数日志保存到文件中,但将分类为紧急或严重错误的日志条目也发送到 Email 地址。为此,您可以使用 woocommerce_register_log_handlers 过滤器钩子来创建您想要使用的日志处理程序类实例的数组。 一些处理程序类构造函数具有可选参数,您可以在实例化类时使用这些参数来更改其默认行为。
以下是添加 Email 处理程序的示例:
function my_wc_log_handlers( $handlers ) {
$recipients = array( 'wayne@example.com', 'garth@example.com' ); // 将日志发送到多个接收者。
$threshold = 'critical'; // 仅为具有此级别及更高级别的日志发送电子邮件。
$handlers[] = new WC_Log_Handler_Email( $recipients, $threshold );
return $handlers;
}
add_filter( 'woocommerce_register_log_handlers', 'my_wc_log_handlers' );
创建自定义处理程序
您可能希望创建自己的日志处理程序类,以便将日志发送到其他位置,例如 Slack 频道或 InfluxDB 实例。 您的类必须扩展 WC_Log_Handler 抽象类,并实现 WC_Log_Handler_Interface 界面。 WC_Log_Handler_Email 处理程序类提供了一个很好的示例,说明如何设置它。
日志文件存储位置
当使用“文件系统”日志处理程序时,默认情况下,日志文件存储在 WordPress “uploads” 目录中的 wc-logs 子目录中,这意味着它们可能可以公开访问。 WooCommerce 会添加一个 .htaccess 文件以防止访问 wc-logs,但并非所有 Web 服务器都识别该文件。 如果有选项,您可能希望考虑将您的日志文件存储在 Web 根目录之外的目录中。 确保该目录具有与 “uploads” 目录相同的用户/组 权限,以便 WordPress 可以访问它。 然后,使用 woocommerce_log_directory 过滤器钩子来设置指向您自定义目录的路径。
禁用冗余日志
如果某个日志信息频繁出现,并且阻塞了您的日志文件,您应该尝试找出它为什么会频繁触发,并解决问题。 但是,如果无法解决,您可以向 woocommerce_logger_log_message 过滤器钩子添加一个回调函数,以忽略该特定日志信息,同时允许其他日志信息通过:
function my_ignored_logs( $message, $level, $context, $handler ) {
if ( false !== strpos( $message, 'Look, a squirrel!' ) ) {
return null;
}
return $message;
}
add_filter( 'woocommerce_logger_log_message', 'my_ignored_logs', 10, 4 );
日志界面
如果您创建了一个自定义日志句柄,并且希望在该日志句柄上构建一个独立的界面,您可以使用以下几个过滤器钩子:
woocommerce_logger_handler_options: 此过滤器钩子允许您将自定义日志句柄添加到“日志存储”选项的列表中,位于“设置”界面。 必须首先选择您的句柄,使其成为“默认”日志句柄,然后才能为其渲染替代界面。wc_logs_render_page: 这是用于渲染您自己的日志界面的动作钩子。 它仅在默认日志句柄设置为内置句柄之外的选项时才会触发。wc_logs_load_tab: 此动作在日志选项卡首次加载时触发,在任何内容输出之前。 它对于处理表单提交非常有用。
0043-best-practices-data-management-docs-data-storage
title: "数据存储基础" post_status: publish comment_status: open taxonomy: category: - woocommerce post_tag: - Data Management - Best Practices - Repos
post_title: 数据存储基础
sidebar_label: 数据存储
---
# 数据存储基础
在为 WordPress 和 WooCommerce 开发时,重要的是要考虑数据的性质和持久性。这将帮助您决定最佳的存储方式。以下是一个简要的介绍:
## 瞬态
如果数据可能并不总是存在(即,它会过期),请使用 [瞬态](https://developer.wordpress.org/apis/handbook/transients/)。瞬态是一种简单且标准化的方法,用于在数据库中临时存储缓存数据,通过为其指定自定义名称和过期时间,在过期后自动删除。
## WP Cache
如果数据是持久的,但并不总是存在,请考虑使用 [WP Cache](https://developer.wordpress.org/reference/classes/wp_object_cache/)。WP Cache 函数允许您缓存计算成本高昂的数据,例如复杂的查询结果。
## wp_options 表
如果数据是持久的并且始终存在,请考虑 [wp_options 表](https://developer.wordpress.org/apis/handbook/options/)。选项 API 是一种简单且标准化的方法,用于在 WordPress 数据库的 wp_options 表中存储数据。
## 帖子类型
如果数据类型是具有 n 个单位的实体,请考虑使用 [帖子类型](https://developer.wordpress.org/post_type/)。帖子类型是内容的一种“类型”,它们以相同的方式存储,但在代码和 UI 中易于区分。
## 分类法
如果数据是用于对实体进行排序/分类的手段,请考虑使用 [分类法](https://developer.wordpress.org/taxonomy/)。分类法是一种将事物分组的方法。
## 日志记录
日志应使用 [WC_Logger](https://woocommerce.com/wc-apidocs/class-WC_Logger.html) 类写入文件。这是一种简单且标准化的方法,用于记录事件和错误,以便进行调试。
请记住,最佳的数据存储方法取决于数据的性质以及它将在您的应用程序中如何使用。
使用 WooCommerce CRUD 对象进行开发
CRUD 是您可以对数据库或资源执行的四种基本操作的缩写——创建、读取、更新、删除。
WooCommerce 3.0 引入了 CRUD 对象用于处理 WooCommerce 数据。在您的代码中,应尽可能使用这些对象,而不是直接更新元数据或使用 WordPress 文章对象。
每个对象都包含其控制数据的结构化数据(属性)、每个属性的 getter 和 setter,以及与数据存储交互的保存/删除方法。数据存储处理从数据库的实际保存/读取。对象本身无需知道数据存储在哪里。
CRUD 的优势
- 结构 - 每个对象都有预定义的结构并保持其自身数据有效。
- 控制 - 我们控制数据流以及任何所需的验证,因此我们知道何时发生更改。
- 易于开发 - 作为开发人员,您无需了解所处理数据的内部细节,只需知道其名称。
- 抽象 - 数据可以移动到其他地方,例如自定义表,而不会影响现有代码。
- 统一 - 我们可以使用相同的代码在管理员界面、REST API 和 CLI 中更新内容。一切都是统一的。
- 简化代码 - 用于更新对象的程序性代码更少,这降低了故障可能性并增加了单元测试覆盖率。
CRUD 对象结构
WC_Data 类是 CRUD 对象的基本实现,所有 CRUD 对象都继承自它。最重要的属性是 $data(一个包含每个对象所支持属性的数组)和 $id(对象的 ID)。
优惠券对象类 是扩展 WC_Data 并为所有属性添加 CRUD 函数的一个很好的例子。
数据
$data 存储属性名称和默认值:
/**
* 数据数组,包含默认值。
* @since 3.0.0
* @var array
*/
protected $data = array(
'code' => '',
'amount' => 0,
'date_created' => '',
'date_modified' => '',
'discount_type' => 'fixed_cart',
'description' => '',
'date_expires' => '',
'usage_count' => 0,
'individual_use' => false,
'product_ids' => array(),
'excluded_product_ids' => array(),
'usage_limit' => 0,
'usage_limit_per_user' => 0,
'limit_usage_to_x_items' => 0,
'free_shipping' => false,
'product_categories' => array(),
'excluded_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'email_restrictions' => array(),
'used_by' => array(),
);
Getter 与 Setter 方法
此数组(属性)中的每个键都对应一个 getter 和 setter 方法,例如 set_used_by() 和 get_used_by()。$data 本身是私密的,因此必须使用 getter 和 setter 方法来访问数据。
Getter 示例:
/**
* 获取所有使用过当前优惠券的用户记录。
* @since 3.0.0
* @param string $context
* @return array
*/
public function get_used_by( $context = 'view' ) {
return $this->get_prop( 'used_by', $context );
}
Setter 示例:
/**
* 设置哪些用户使用过此优惠券。
* @since 3.0.0
* @param array $used_by
* @throws WC_Data_Exception
*/
public function set_used_by( $used_by ) {
$this->set_prop( 'used_by', array_filter( $used_by ) );
}
set_prop 和 get_prop 是 WC_Data 的一部分。它们会应用各种过滤器(基于上下文)并处理变更,因此我们可以高效地仅保存已更改的属性,而不是所有属性。
关于 $context 的说明:当获取用于前端或显示的数据时,使用 view 上下文。这会对数据应用过滤器,以便扩展可以动态更改值。在后台显示要编辑的值以及保存到数据库时,应使用 edit 上下文。使用 edit 上下文不会对数据应用任何过滤器。
构造函数
CRUD 对象的构造函数便于从数据库读取数据。实际的读取操作并非由 CRUD 类执行,而是由其数据存储完成。
示例:
/**
* 优惠券构造函数。加载优惠券数据。
* @param mixed $data 优惠券数据、对象、ID 或代码。
*/
public function __construct( $data = '' ) {
parent::__construct( $data );
if ( $data instanceof WC_Coupon ) {
$this->set_id( absint( $data->get_id() ) );
} elseif ( is_numeric( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
$this->set_id( $data );
} elseif ( ! empty( $data ) ) {
$this->set_id( wc_get_coupon_id_by_code( $data ) );
$this->set_code( $data );
} else {
$this->set_object_read( true );
}
$this->data_store = WC_Data_Store::load( 'coupon' );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
}
请注意它如何根据传递给对象的数据设置 ID,然后调用数据存储从数据库检索数据。一旦通过数据存储读取了数据,或者未设置 ID,就会设置 $this->set_object_read( true );,以便数据存储和 CRUD 对象知道它已被读取。设置此标志后,系统将开始跟踪更改。
保存与删除
在 CRUD 子类中,保存和删除方法是可选的,因为 WC_Data 父类可以处理它们。当调用 save 时,数据存储用于将数据保存到数据库。Delete 则从数据库中移除对象。必须调用 save 才能使更改持久化,否则它们将被丢弃。
WC_Data 中的 save 方法如下所示:
/**
* Save should create or update based on object existence.
*
* @since 2.6.0
* @return int
*/
public function save() {
if ( $this->data_store ) {
// 在保存到数据库前触发操作。允许您在保存前调整对象属性。
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
return $this->get_id();
}
}
根据对象是否已有 ID,使用更新/创建。ID 将在创建后设置。
delete 方法如下:
/**
* Delete an object, set the ID to 0, and return result.
*
* @since 2.6.0
* @param bool $force_delete
* @return bool result
*/
public function delete( $force_delete = false ) {
if ( $this->data_store ) {
$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
$this->set_id( 0 );
return true;
}
return false;
}
CRUD 用法示例
创建新的简单产品
$product = new WC_Product_Simple();
$product->set_name( 'My Product' );
$product->set_slug( 'myproduct' );
$product->set_description( 'A new simple product' );
$product->set_regular_price( '9.50' );
$product->save();
$product_id = $product->get_id();
更新现有优惠券
$coupon = new WC_Coupon( $coupon_id );
$coupon->set_discount_type( 'percent' );
$coupon->set_amount( 25.00 );
$coupon->save();
获取客户信息
$customer = new WC_Customer( $user_id );
$email = $customer->get_email();
$address = $customer->get_billing_address();
$name = $customer->get_first_name() . ' ' . $customer->get_last_name();
优惠券管理
本页面用于管理优惠券。您可以查看、创建、编辑和删除优惠券。
- 新增优惠券:点击“新增”按钮,可以创建新的优惠券。
- 编辑优惠券:点击优惠券列表中的“编辑”按钮,可以修改现有优惠券的设置。
- 删除优惠券:点击优惠券列表中的“删除”按钮,可以删除优惠券。
优惠券详情
显示单个优惠券的详细信息,包括:
- 名称 (Name):优惠券的名称。
- 折扣 (Discount):优惠券的折扣类型和金额。
- 使用 (Use):优惠券的使用限制,例如最小订单金额、使用次数等。
- 有效期 (Expiration Date):优惠券的有效期。
- 其他设置 (Other Settings):其他自定义设置。
优惠券列表
显示所有优惠券的列表,包括:
- 名称 (Name):优惠券的名称。
- 折扣 (Discount):优惠券的折扣类型和金额。
- 使用次数 (Count):优惠券已使用的次数。
- 状态 (Status):优惠券的状态,例如“有效”、“已过期”、“已禁用”。
批量操作
您可以对多个优惠券进行批量操作,例如:
- 删除 (Delete):删除选中的优惠券。
- 更新 (Updating):更新选中的优惠券的状态。
导入/导出
您可以将优惠券数据从一个系统导入到另一个系统,或者将优惠券数据导出为文件。
- 导入 (Import):从文件导入优惠券数据。
- 导出 (Export):将优惠券数据导出为文件。
优惠券代码
以下是一些常用的优惠券代码示例:
%s:占位符,表示用户可以自定义的文本。{name}:占位符,表示客户的名称。
邮件通知
当客户使用优惠券时,您可以发送电子邮件通知。
- 邮件 (Mail):发送电子邮件通知。
- 收件人 (Address):收件人的电子邮件地址。
- 主题 (Subject):电子邮件的主题。
- 正文 (Body):电子邮件的正文内容。
账单 (Billing)
显示与优惠券相关的账单信息。
- 金额 (Amount):优惠券的金额。
- 百分比 (Percent):优惠券的百分比折扣。
- 类型 (Type):优惠券的类型。
常见问题
- 如何创建新的优惠券? 点击“新增”按钮,填写优惠券的详细信息,然后点击“保存”按钮。
- 如何修改现有优惠券? 点击优惠券列表中的“编辑”按钮,修改优惠券的设置,然后点击“保存”按钮。
- 如何删除优惠券? 点击优惠券列表中的“删除”按钮,确认删除操作。
- 如何使用优惠券? 在结账时,输入优惠券代码,系统会自动应用折扣。
- 优惠券的有效期是什么? 优惠券的有效期由您在创建优惠券时设置。
- 如何查看优惠券的使用情况? 在优惠券详情页面,您可以查看优惠券的使用次数和状态。
- 如何导出优惠券数据? 点击“导出”按钮,选择导出的文件格式,然后点击“下载”按钮。
- 如何导入优惠券数据? 点击“导入”按钮,选择要导入的文件,然后点击“上传”按钮。
错误信息
Invalid coupon code.:优惠券代码无效。Coupon has expired.:优惠券已过期。Coupon has already been used.:优惠券已使用。Minimum order amount not met.:未达到最小订单金额。Coupon cannot be applied to this product.:该优惠券无法应用于该商品。Error updating coupon.:更新优惠券时出错。Error deleting coupon.:删除优惠券时出错。Error importing coupon data.:导入优惠券数据时出错。Error exporting coupon data.:导出优惠券数据时出错。
提示
- 您可以使用搜索框快速查找优惠券。
- 您可以使用分页功能浏览优惠券列表。
- 您可以使用排序功能对优惠券列表进行排序。
- 您可以使用过滤器功能筛选优惠券列表。
- 如果您在使用优惠券时遇到问题,请联系客服。
- 请定期检查和更新您的优惠券,以确保其有效性。
- 您可以创建自定义的优惠券代码,以满足您的特定需求。
- 您可以
更新国家和行政区划
WooCommerce 包含一个全面的国家和行政区划(例如省份或州)列表,这些列表用于用户界面的各个部分。
当然,国家及其行政区划也会定期发生变化。 在这些情况下,您可以提交一个 问题报告 或 提交一个拉取请求。 但是,重要的是要理解,我们的政策只接受与当前版本的 CLDR 项目 保持一致的更改。 因此,通常最好先查看该项目,如果需要,首先在该项目上提出更改,然后再要求 WooCommerce 采用这些更改。
这种方法可能不适用于所有情况,因为 CLDR 接受更新可能需要时间。 在这种情况下,您仍然可以使用自定义代码片段来修改国家和行政区划的列表,例如以下代码片段:
如何翻译 WooCommerce
WooCommerce 已经翻译成多种语言,并且开箱即用,支持翻译。 只需要一个用于您语言的翻译文件即可。
创建翻译的方法有很多,大多数方法都已在 WordPress Codex 中详细说明。 在大多数情况下,您可以访问 https://translate.wordpress.org/projects/wp-plugins/woocommerce/ 参与该项目。
要创建自定义翻译,您可以考虑使用 Poedit。
设置您网站的语言
要设置您的 WordPress 网站的语言:
- 转到
WP Admin > 设置 > 常规,并调整Site Language。 - 转到
WP Admin > 仪表盘 > 更新,然后单击更新翻译按钮。
完成这些操作后,如果语言文件存在,商店将以您的本地语言显示。 否则,您需要创建语言文件(具体过程如下所述)。
向核心贡献您的本地化版本
我们鼓励对翻译做出贡献。 如果您想添加已翻译的字符串或开始一个新的翻译,只需在 WordPress.org 上注册,并将您的翻译提交到 https://translate.wordpress.org/projects/wp-plugins/woocommerce/ 以供审核。
将 WooCommerce 翻译成您的语言
WooCommerce 的稳定版本和开发版本都可供翻译。 当您安装或更新 WooCommerce 时,WordPress 将自动获取您语言的完整翻译。 如果没有可用的翻译,您可以手动下载,或者贡献以完成翻译,从而使所有用户受益。
如果您是翻译新手,请查看 译者手册 以开始您的翻译之旅。
手动从 translate.wordpress.org 下载翻译
-
访问 translate.wordpress.org 并在该列表中查找您的语言。
-
点击标题,进入该语言的对应部分。

-
点击
Set/Sub Project下方的标题,以查看和下载稳定版本的翻译。
-
滚动到页面底部,找到导出选项。 导出
.mo文件,以便在您的网站中使用。 -
将该文件重命名为
woocommerce-YOURLANG.mo(例如,对于英国英语,应为en_GB)。 相应的语言代码可以在访问 https://translate.wordpress.org/projects/wp-plugins/woocommerce/ 并打开所需的语言时找到。 语言代码显示在右上角。
-
将文件上传到
wp-content/languages/woocommerce/目录。 上传后,即可使用此翻译文件。
创建自定义翻译
WooCommerce 包含一个语言文件 (.pot 文件),其中包含所有英文文本。 您可以在插件文件夹的 woocommerce/i18n/languages/ 目录中找到此语言文件。
使用 PoEdit 创建自定义翻译
WooCommerce 附带一个 .pot 文件,可以将其导入到 PoEdit 中进行翻译。
开始步骤:
-
打开 PoEdit,选择
Create new translation from POT template(从 POT 模板创建新的翻译)。 -
选择
woocommerce.pot,PoEdit 将显示目录属性窗口。
-
输入您的姓名和详情,以便其他译: 知道您的身份,然后点击
OK。 -
保存您的
.po文件。 根据您要翻译的内容命名,例如,对于英国的翻译,应保存为woocommerce-en_GB.po。 现在,字符串列表将显示。
-
在翻译字符串后保存。
.mo文件将自动生成。 -
打开您的
.po文件,然后转到Catalog > Update from POT file(目录 > 从 POT 文件更新)以更新您的.po文件。 -
选择文件,它将被相应地更新。
确保您的翻译升级安全
WooCommerce 将翻译文件保存在 wp-content/languages/plugins 目录下,与其他所有插件一样。但是,如果您希望包含自定义翻译,可以使用 wp-content/languages/woocommerce 目录,或者可以使用一段代码来加载存储在其他位置的自定义翻译:
// 将以下代码放置在您主题的 functions.php 文件或自定义插件文件中。
add_filter( 'load_textdomain_mofile', 'load_custom_plugin_translation_file', 10, 2 );
/**
* 将 'textdomain' 替换为您的插件的 textdomain。例如:'woocommerce'。
* 文件的命名方式,例如:yourtranslationfile-en_GB.mo
* 文件的放置位置,例如:wp-content/languages/textdomain/yourtranslationfile-en_GB.mo
*/
function load_custom_plugin_translation_file( $mofile, $domain ) {
if ( 'textdomain' === $domain ) {
$mofile = WP_LANG_DIR . '/textdomain/yourtranslationfile-' . get_locale() . '.mo';
}
return $mofile;
}
其他工具
有一些其他的第三方工具可以帮助您进行翻译。以下列表显示了一些工具。
Loco Translate
Loco Translate 提供了在浏览器中编辑 WordPress 翻译文件的功能,并与自动翻译服务进行集成。
Say what?
Say what? 允许您轻松地翻译或修改特定的单词,而无需深入到 WordPress 主题的 .po 文件中。
String locator
String Locator 允许您快速在主题、插件或 WordPress 核心中进行搜索,并显示包含匹配文本的文件列表以及其行号。
常见问题解答
为什么结账页面的某些字符串没有被翻译?
您可能会发现,结账页面上的某些字符串没有被翻译。例如,在下面的截图中,本地自提 配送方式、货到付款 支付方式以及与隐私政策相关的信息都没有被翻译成俄语,而表单的其余部分确实被翻译了:

这种情况通常发生在您首次安装 WooCommerce 并选择默认站点语言(英语),然后更改站点语言为另一种语言时。在 WooCommerce 中,与屏幕截图中的未翻译字符串相关的信息,会在初始 WooCommerce 安装后存储在数据库中。因此,如果站点语言更改为另一种语言,WooCommerce 无法检测到可翻译的字符串,因为这些是数据库条目。
要解决此问题,请导航到与您需要更改的字符串对应的 WooCommerce 设置,并在那里直接更新翻译。例如,要修复我们上述情况中的字符串,您需要执行以下操作:
本地自提:
- 转到
WooCommerce > 设置 > 配送 > 配送区域。 - 选择包含“本地自提”的配送区域。
- 打开“本地自提”设置。
- 使用您的翻译重命名该方法。
- 保存设置。
货到付款:
- 转到
WooCommerce > 设置 > 支付。 - 选择“货到付款”支付方式。
- 打开其设置。
- 使用您的翻译重命名该方法的标题、描述和说明。
- 保存设置。
隐私政策信息:
- 转到
WooCommerce > 设置 > 账户与隐私。 - 滚动到“隐私政策”部分。
- 使用您的翻译编辑“注册隐私政策”和“结账隐私政策”字段。
- 保存设置。
返回结账页面 - 翻译应该会反映在那里。
我已经翻译了需要的字符串,但有些字符串在前端没有显示翻译结果。为什么?
如果您的 WooCommerce 网站上的一些已翻译字符串没有按预期显示,首先需要检查这些字符串在源文本部分是否同时具有单数和复数形式。为此,请打开相应的翻译,例如,在 https://translate.wordpress.org/projects/wp-plugins/woocommerce/ 上,查看“产品”和“项目”的翻译,例如 产品和项目的翻译。
此截图显示单数形式的翻译是可用的:

而此截图显示复数形式的翻译是无法使用的:

更新国家和行政区划
WooCommerce 包含一个全面的国家和行政区划(例如省份或州)列表,这些列表用于用户界面的各个部分。
当然,国家及其行政区划也会定期发生变化。 在这些情况下,您可以提交一个 问题报告 或 提交一个拉取请求。 但是,重要的是要理解,我们的政策只接受与当前版本的 CLDR 项目 保持一致的更改。 因此,通常最好先查看该项目,如果需要,首先在该项目上提出更改,然后再要求 WooCommerce 采用这些更改。
这种方法可能不适用于所有情况,因为 CLDR 接受更新可能需要时间。 在这种情况下,您仍然可以使用自定义代码片段来修改国家和行政区划的列表,例如以下代码片段:
如何配置 WooCommerce 的缓存插件
从缓存中排除网页
通常,在使用缓存插件时,它们已经会自动排除某些网页。如果不是,请确保通过缓存系统的相应设置,从缓存中排除以下网页:
- 购物车
- 我的账户
- 结账
这些网页需要保持动态状态,因为它们显示特定于当前客户及其购物车的信息。
从缓存中排除 WooCommerce 会话
如果使用的缓存系统提供数据库缓存功能,那么将 _wc_session_ 从缓存中排除可能会有所帮助。这取决于插件或主机缓存的配置,请参考该系统的具体说明或文档。
从缓存中排除 WooCommerce Cookie
WooCommerce 中的 Cookie 用于跟踪客户购物车的产品,可以保留客户离开网站时的购物车数据,并驱动“最近浏览”小工具。以下是 WooCommerce 使用的 Cookie 列表,您可以将它们从缓存中排除。
| COOKIE 名称 | 持续时间 | 作用 |
|---|---|---|
| woocommerce_cart_hash | 会话 | 帮助 WooCommerce 确定购物车内容/数据何时发生变化。 |
| woocommerce_items_in_cart | 会话 | 帮助 WooCommerce 确定购物车内容/数据何时发生变化。 |
| wp_woocommerce_session_ | 2 天 | 包含每个客户的唯一代码,以便知道在数据库中为每个客户查找购物车数据的位置。 |
| woocommerce_recently_viewed | 会话 | 驱动“最近浏览产品”小工具。 |
| store_notice[notice id] | 会话 | 允许客户不再显示商店通知。 |
我们无法涵盖所有选项,但我们添加了一些关于常用缓存插件的提示。如需更具体的支持,请联系负责您缓存集成的支持团队。
W3 Total Cache 压缩设置
请确保在“压缩”设置中的“忽略的注释开头”选项中添加 'mfunc'。
WP-Rocket
WooCommerce 与 WP-Rocket 完全兼容。请确保在插件的设置中,不要将以下网页(购物车、结账、我的账户)缓存。
我们建议避免 JavaScript 文件压缩。
WP Super Cache
WooCommerce 原生支持 WP Super Cache。WooCommerce 会向 WP Super Cache 发送信息,以便默认情况下不缓存购物车、结账或我的账户网页。
Varnish
if (req.url ~ "^/(cart|my-account|checkout|addons)") {
return (pass);
}
if ( req.url ~ "\\?add-to-cart=" ) {
return (pass);
}
故障排除
为什么我的 Varnish 配置在 WooCommerce 中无法正常工作?
请查看 WordPress.org 上的以下支持论坛帖子,了解cookie 如何影响您的 Varnish 配置。
在 "if (req.http.cookie) {" 之前,添加以下内容:
# 移除除了 WordPress 管理和 WooCommerce 页面之外的所有 Cookie
if (!(req.url ~ "(wp-login|wp-admin|cart|my-account/*|wc-api*|checkout|addons|logout|lost-password|product/*)")) {
unset req.http.cookie;
}
# 允许访问 WooCommerce 动态页面
if (req.url ~ "^/(cart|my-account/*|checkout|wc-api/*|addons|logout|lost-password|product/*)") {
return (pass);
}
# 允许访问 WooCommerce 的“加入购物车”功能
if (req.url ~ "\?add-to-cart=") {
return (pass);
}
# 允许访问 WooCommerce API
if (req.url ~ "\?wc-api=") {
return (pass);
}
# 通过网站阻止访问 php 管理页面
if (req.url ~ "^/phpmyadmin/.*$" || req.url ~ "^/phppgadmin/.*$" || req.url ~ "^/server-status.*$") {
error 403 "出于安全原因,此 URL 只能通过主机名为 localhost (127.0.0.1) 的方式访问";
}
在 vcl_fetch 中添加以下内容:
# 移除除了 WordPress 管理和 WooCommerce 页面之外的所有 Cookie
if ( (!(req.url ~ "(wp-(login|admin)|login|cart|my-account/*|wc-api*|checkout|addons|logout|lost-password|product/*)")) || (req.request == "GET") ) {
unset beresp.http.set-cookie;
}
为什么我的密码重置功能陷入循环?
这是因为“我的账户”页面被缓存了。 一些具有服务器端缓存的主机可能不会阻止 my-account.php 被缓存。
如果您无法重置密码,并且始终返回到登录页面,请联系您的主机,以确保该页面已从其缓存中排除。
WooCommerce 扩展的性能最佳实践
优化 WooCommerce 扩展的性能对于确保在线商店的流畅运行、提供卓越的用户体验以及在搜索引擎结果中获得良好的排名至关重要。 本指南专为希望提高 WooCommerce 扩展的速度和效率的开发者而设计,重点在于理解性能影响、基准测试、测试以及实施改进策略。
性能优化
对于 WooCommerce 扩展,性能优化意味着确保您的代码能够为快速、响应的用户体验做出贡献,同时避免增加不必要的加载时间和资源消耗。
为什么性能至关重要
- 用户体验: 性能良好的扩展有助于提供无缝的购物体验,鼓励客户完成购买。
- 商店性能: 扩展会显著影响 WooCommerce 商店的整体速度; 优化的扩展有助于保持最佳的网站性能。
- SEO 和转化率: 速度是 SEO 排名和转化率的关键因素。 高效的扩展有助于提高商店的排名和更高的转化率。
性能基准测试
为 WooCommerce 扩展的开发和持续改进设定明确的性能基准至关重要。 推荐的性能标准是在一个简单的 Woo 网站上,使用诸如 Chrome Lighthouse 之类的工具,实现 Chrome Core Web Vitals "Performance" 分数 90 或以上。
使用易于访问的工具进行基准测试
Chrome Lighthouse 提供了一个全面的框架来评估网页的性能,包括受您的 WooCommerce 扩展影响的网页。 通过将 Lighthouse 测试集成到您的开发流程中,您可以尽早识别和解决性能问题。
我们建议利用这些工具来评估您的扩展对 WooCommerce 商店性能的影响,并找出需要改进的领域。
性能提升策略
优化 WooCommerce 扩展的性能涉及以下几个关键策略:
- 优化资源加载: 确保脚本和样式仅在需要时才加载,采用条件加载的方式。
- 高效的数据库查询: 优化数据库交互,以最大限度地减少查询时间和资源消耗。 适当使用索引,并避免不必要的
Data检索。 - 延迟加载: 为您的扩展加载的
Images和内容实现延迟加载,以减少初始Page加载时间。 - 压缩和合并: 压缩 CSS 和 JavaScript 文件,并在可能的情况下将它们合并,以减少 HTTP
Requests的数量。 - 在启用和禁用扩展时进行测试: 定期测试启用和禁用您的扩展的 WooCommerce
Store,以便清楚地了解其对性能的影响。 - 缓存支持: 确保您的扩展与流行的缓存解决方案兼容,并避免可能不必要地绕过或
Clear Cache的Actions。
通过遵循这些最佳实践,并定期对您的扩展进行基准测试和测试,您可以确保它能够提升,而不是降低,WooCommerce Store 的性能。 实施这些策略将带来更高效、加载速度更快的扩展,这将受到 Store 所有者及其 Customers 的赞赏。
如何优化 WooCommerce 商店的性能
简介
本指南涵盖了优化 WooCommerce 商店性能的最佳实践和技术,包括缓存、图像优化、数据库维护、代码压缩以及使用内容分发网络 (CDN)。 通过遵循这些建议,开发者可以构建高性能的 WooCommerce 商店,从而提供更好的用户体验并提高转化率。
目标读者
本指南面向熟悉 WordPress 和 WooCommerce 且希望提高其在线商店性能的开发者。
前置条件
要遵循本指南,您应该具备:
- 对 WordPress 和 WooCommerce 的基本了解。
- 访问已安装并启用的 WooCommerce 的 WordPress 网站。
第一步 - 实施缓存
缓存在加速您的 WooCommerce 商店方面起着至关重要的作用,它通过向访问者提供页面的静态版本来减少服务器的负载。 有几种方法可以为您的 WooCommerce 商店实施缓存:
服务器端缓存
通过您的托管服务提供商或使用服务器级别的缓存解决方案(如 Varnish、NGINX FastCGI Cache 或 Redis)启用服务器端缓存。
WordPress 缓存插件
安装并配置一个 WordPress 缓存插件,例如 WP Rocket、W3 Total Cache 或 WP Super Cache。 这些插件可以帮助您设置 WooCommerce 商店的页面缓存、浏览器缓存和对象缓存。
WooCommerce 专用缓存
确保您的缓存解决方案已正确配置,以便允许动态内容(例如购物车和结账页面)不被缓存。 一些缓存插件,例如 WP Rocket,内置了对 WooCommerce 缓存的支持。
第二步 - 优化图像
优化图像可以通过减少图像文件的大小(而不影响质量)来显着提高商店的性能。 要优化 WooCommerce 商店中的图像:
- 使用正确的图像格式:为您的图像选择合适的格式,例如 JPEG 用于照片,PNG 用于具有透明度的图形。
- 压缩图像:使用图像压缩工具(如 TinyPNG 或 ShortPixel)在将它们上传到商店之前减小文件大小。
- 启用延迟加载:延迟加载会在需要时才加载图像,从而提高初始页面加载时间。 许多缓存插件和性能优化插件提供内置的延迟加载选项。
- 使用响应式图像:确保您的主题和插件为不同的设备和屏幕分辨率提供适当大小的图像。
第三步 - 压缩和优化代码
压缩和优化商店的 HTML、CSS 和 JavaScript 文件可以帮助减小文件大小并提高网页加载速度。要为您的 WooCommerce 商店压缩和优化代码:
- 使用插件:安装一个性能优化插件,例如 Autoptimize、WP Rocket 或 W3 Total Cache,以压缩和优化商店的 HTML、CSS 和 JavaScript 文件。
- 组合并内联关键 CSS:尽可能地组合并内联关键 CSS,以减少请求数量并提高网页加载速度。
- 延迟加载非关键 JavaScript:延迟加载非关键 JavaScript 文件,以提高 perceived 网页加载速度。
第四步 - 使用内容分发网络 (CDN)
内容分发网络 (CDN) 可以通过从分布在全球各地的服务器网络中提供静态资源,例如图像、CSS 和 JavaScript 文件,来提高您的 WooCommerce 商店的性能。要为您的 WooCommerce 商店使用 CDN:
- 选择 CDN 提供商:选择一个适合您的需求和预算的 CDN 提供商,例如 Cloudflare、Fastly 或 Amazon CloudFront。
- 设置您的 CDN:按照您选择的 CDN 提供商的说明,设置和配置 CDN 以用于您的 WooCommerce 商店。
第五步 - 优化数据库
定期优化您的 WordPress 数据库可以帮助提高 WooCommerce 商店的性能,方法是删除不必要的数据并优化数据库表。要优化您的数据库:
- 使用插件:安装一个数据库优化插件,例如 WP-Optimize、WP-Sweep 或 Advanced Database Cleaner,以清理和优化您的 WordPress 数据库。
- 删除不必要的数据:定期删除垃圾评论、文章修订和过期的瞬态数据,以减少数据库的冗余。
- 优化数据库表:使用数据库优化插件来优化您的数据库表,提高其效率并减少查询时间。
第六步 - 选择高性能的主题和插件
您为 WooCommerce 商店选择的主题和插件会对性能产生重大影响。为了确保您的商店运行高效:
- 选择一个轻量级、性能优化的主题:选择一个专门为 WooCommerce 设计的主题,该主题优先考虑性能并遵循最佳编码实践。
- 评估插件性能:使用工具,例如 Query Monitor 或 WP Hive,来分析您安装的插件对性能的影响,并移除或替换那些对商店性能产生负面影响的插件。
第七步 - 启用 GZIP 压缩
GZIP 压缩可以帮助减小商店的 HTML、CSS 和 JavaScript 文件的尺寸,从而提高网页加载速度。要启用 GZIP 压缩:
- 使用插件:安装一个性能优化插件,例如 WP Rocket、W3 Total Cache 或 WP Super Cache,该插件包含 GZIP 压缩选项。
- 配置您的服务器:或者,通过修改您的 .htaccess 文件(适用于 Apache 服务器)或 nginx.conf 文件(适用于 NGINX 服务器),直接在您的服务器上启用 GZIP 压缩。
第 8 步 - 监控和分析性能
持续监控和分析您的 WooCommerce 商店的性能,以识别潜在的瓶颈和需要改进的方面。为了监控和分析性能:
- 使用性能测试工具:定期使用诸如 Google PageSpeed Insights、GTmetrix 或 WebPageTest 之类的工具测试您的商店的性能。
- 实施性能监控:安装一个性能监控插件,例如 New Relic,或者使用一个监控服务,例如 Uptime Robot,以跟踪您的商店的性能。
结论
通过遵循这些最佳实践和性能优化技术,您可以构建一个高性能的 WooCommerce 商店,它能提供更好的用户体验,并有助于提高转化率。持续监控和分析您的商店的性能,以确保它在您的商店成长和发展时保持优化。
如何请求 WooCommerce 插件评论
请求评论的方法
后台通知
后台通知是请求评论的常用方法,但过度使用后台通知会降低效果。 我们建议在通知的设计上保持克制,并且每次只显示一个通知。 过多的或过于 intrusive 的通知很容易让商家感到厌烦。
建议
- 插件评论的后台通知最好显示在
Plugins页面以及插件的设置页面。 - 在通知中包含一个或多个“稍后提醒”选项,并明确告知用户下次通知出现的时间。
- 后台通知必须始终可以被完全关闭。 仅提供“稍后提醒”选项是不够的。
- 通知中呈现的选项必须措辞谨慎,避免使用具有操纵性的语言。
- 使用一致的设计风格,使评论请求成为插件的一部分,并与 WooCommerce 的设计保持一致。
客户直接联系
建议
- 请求评论的最佳方式是,在客户对产品最满意时直接联系他们,这样成功的几率最高。
- 这可以通过里程碑或时间来触发,遵循以下时间指导原则。
- 最佳方法是发送电子邮件或其他直接沟通(支持聊天、电话等)。 这种方式的转化率最高,尤其是在时间恰当的情况下,即在客户最满意的时候。
- 当您可以从特定类型的商家那里收集反馈时,这种方法也非常有效,例如,那些通过您的平台处理了特定金额的商家,或者使用您的物流插件完成了前 100 个订单的商家。
- 直接沟通最有可能成功,如果您有方法可以针对特定用户发送评论请求(例如,商家账户/使用信息),并且有收集评论的渠道,例如销售或市场团队可以通过电子邮件/电话/聊天与商家沟通。
请求评论的文案
我们推荐的一种请求反馈的方法是使用 NPS 风格的评论征集方式。 这种方式可以增加正面评论的数量,同时也能为那些遇到困难的商家提供帮助。
NPS 风格的评论首先询问用户对产品的评分(满分 5 星),然后根据用户的回复进行不同的处理:
- 如果用户点击 4 或 5 星,则提示他们留下评论。
- 如果用户点击 1、2 或 3 星,则告知他们我们在这里提供帮助,并请他们提交支持工单。
在与支持人员进行积极的互动后,商家更有可能留下评论。 类似“感谢我的最佳方式是留下一个带有我的名字的 5 星评论”的说法通常效果很好——人们更愿意帮助一个人,而不是一个产品或公司。
各种建议和指导
与搜索词直接匹配的贡献者姓名将在 WordPress.org 插件库中获得极高的排名,这意味着如果您的 WordPress.org 用户名以您的业务命名(如果该名称是您插件的搜索词),可能会对竞争插件产生不利影响。
持续的提示和在管理员仪表盘上显示不必要的警报会降低用户体验。
您可以请求移除那些实际上不是反馈的评论。例如,如果评论只是一个简单的支持请求,并且明显放在了错误的位置,则可以考虑移除。即使是带有负面情绪的 1 星评论通常也不会被移除。
回复评论!感谢提供反馈的人,如果需要,承认问题,要求提供更具体的反馈,或者在问题得到解决时提供更新!您的评论是了解您的扩展程序用户的真实想法的重要途径。
让与扩展程序开发密切相关的人员(例如开发者和项目经理)定期查看评论,是确保客户的声音被听到的好方法。1 星评论通常最有价值,只要问题能够被理解和解决(如果需要)。
向用户通报错误修复和功能请求
一个错误或缺失的功能可能会对商家造成重大影响。 堆积的错误或未实现的流行功能可能导致负面评论,以及商家流失并寻找竞争解决方案。
通常,错误会通过支持渠道或 GitHub 报告,或者您可以在测试过程中自行发现。
当发现一个严重错误时,应在几天内解决它(大多数严重错误应在 24 小时内解决),并迅速发布一个新的插件版本。 您的发布流程的一部分应该是通知所有利益相关者(支持团队和受影响的商家)即将发布的版本。
即使一个严重错误给商家带来了很大的压力,但快速的解决能够让商家感到被倾听和被支持。 拥有一个可靠的合作伙伴,尤其是在最困难的情况下愿意提供帮助,有助于建立更牢固的关系。 因此,我们通常会要求商家在交付快速解决方案后给予 5 星的评价。
当您实现一个新的功能请求并发布一个新的插件版本时,您可以遵循与错误修复类似的方法:
- 通知所有利益相关者。
- 在“功能请求”看板中更新相关的请求,通过分享公开的更新并将其标记为“已完成”。
- 对于重大版本发布:与您的市场/公关团队沟通,以便在发布前发布更新/新闻邮件。
如何应对 WooCommerce 插件的负面评价
在商家的使用过程中,可能会遇到一些不愉快的事件,导致他们留下公开的负面评价。这些事件通常包括:
- 产品问题,
- 缺少产品功能,
- 没有提供有用的回复,
- 收到回复的等待时间过长,或者;
- 上述问题的组合。
收到负面评价时,您的目标应该是尽可能地将负面评价转化为正面评价,这听起来可能很困难,但实际上非常有价值。
在大多数情况下,留下负面评价的商家首先尝试联系客服寻求帮助。 这是一个非常有用的信息,因为我们可以查看对话历史,了解商家遇到的问题,并在我们回复时与他们分享更多详情,即使是从我们第一次回复开始。
我们发现以下流程效果良好:
- 创建一个新的回复(通过电子邮件或在公开评价中),主题为:关于您最近对 xxx 的评价。
- 首先,自我介绍,例如:“您好,我是来自开发 xxx 团队的 Andrew”。
- 使用富有同情心的语言,并明确表示这个负面评价对您产生了影响。 例如:“我阅读了您最近对 xxx 的评价,听到您遇到了问题,无法像您预想的那样使用此插件,我感到很担心。我很乐意帮助您解决这个问题!”。
将上面的句子与“我很抱歉您在使用 xxx 时遇到了问题”进行比较。“我很抱歉”表明您对某个事件感到难过,但可能并不打算采取任何行动。 相比之下,“我感到很担心”表明您会采取行动。 此外,“您遇到了问题”可能会被理解为问题主要在于商家,而使用“一个问题正在阻止您像您预想的那样使用此插件,我很乐意帮助您解决这个问题!” 这样的语言,则暗示您和商家是同一战壕里的。
- 分享更多详情、解决方案、想法、建议或解释。
- 鼓励商家更新评价,强调评价对您的团队和其他商家有多重要。 可以使用以下语句:“如果您能花几分钟时间更新您的评价,并描述您与我们的产品和支持的体验,我们将不胜感激。 诚实的评价对其他正在决定某个插件是否适合他们的商家来说非常有帮助。 谢谢您的贡献!”。
- 包含一个直接链接到评价部分,以便商家可以轻松地访问并更改他们的评价。
- 在后续沟通中,如果商家已经更新了评价,可以考虑说:“我将此事分享给了团队的其他成员,这让每个人都感到非常高兴”。
如果上述情况属实,与商家分享您的一些流程(强调您的团队如何重视和依赖反馈)有助于确保商家感到您是他们团队的一员,并与他们建立牢固的关系。
技术文档翻译
即使是那些没有对评价进行更改的商家,也可以通过了解对方的设置并提供一些建议,来进行互利的讨论。 这些对话有助于提高商家的信任度。
Setup
- Suggestions
- Discussion
- About
- Help
View
- Row
- All
- Set
- Off
More
- Sat
- By
- Or
- on
- at
Example:
This is an example of how to use the print() function in Python.
print("Hello, world!")
Explanation:
The print() function takes a string as an argument and prints it to the console.
Further Reading:
Note:
This document is a work in progress and may contain errors. Please report any errors to the author.
Date: %s
Version: %d
Contact: {name}
URL: https://example.com
利用 WooCommerce 扩展的特性请求功能
重要的是要跟踪所有特性请求,并建立一种记录系统,以便任何人都可以了解产品在一段时间内收到的反馈类型。
我们建议每天或每隔一天进行检查,您应该:
- 评估新的特性请求,
- 庆祝积极的评论,以及;
- 采取行动处理负面评论。
仔细维护特性请求看板(或类似的系统)至关重要,因为平均而言,看板包含大量重复/垃圾内容、关于已实现功能的请求以及关于不太可能实现的请求。维护不当的看板会让商家感到被忽视。
这会导致更多负面评论,因为产品团队似乎没有阅读/倾听他们的反馈。
我们已经看到以下流程取得了良好的效果:
从受影响最大的产品开始,逐一查看所有未决请求,回复大部分或全部请求,并将它们分类为:
- "Open"(打开):表示我们仍然希望收到更多反馈的请求,
- "Planned"(计划中):表示我们计划实现的请求,
- "Completed"(已完成):表示已经实现的请求,以及;
- "Closed"(已关闭):表示我们不计划实现的请求,因为它们不适合产品,或者是因为是重复/垃圾请求,或者是因为实际上是支持问题。
回复所有“Open”请求是目标,但如果当前无法实现,请务必回复 100% 的已关闭请求。
对于作为特性请求而收到的新“Open”请求,请进行讨论/评估,并立即回复,并分配一个状态,以避免看板变得“未托管”,并确保商家感到(并且确实)被倾听。
除了一个整洁的看板对商家的积极影响外,它还可以帮助产品团队更好地了解哪些请求是最受欢迎和最具影响力的,然后据此进行工作规划。
如何利用您的支持团队来响应反馈
您的支持团队通常是商家与您联系的主要入口。门票(Tickets)和聊天是与商家沟通的最佳工具,可以帮助我们了解他们对软件的使用情况,倾听他们的反馈,并分析他们的功能请求。 总体而言,支持团队对产品以及用户的使用方式有着深刻的理解。 这些信息对于传递给产品和工程团队至关重要。
我们建议您采取以下步骤,以最佳方式利用您的支持团队:
- 创建严格的内部服务级别协议 (SLA),确保支持团队的请求由产品或工程团队来解答。
- 确保您的支持团队能够有效地向产品和工程团队报告 bug。
- 在回复您的支持团队时,避免使用过于简短的回答,并尝试用简单明了的语言解释答案。 这样可以让支持人员将您的答案复制/粘贴给商家。
- 避免直接回复“不可能”或“该功能不会实现”之类的语句,而应提供有关技术或产品限制的更多上下文信息。
- 定期抽出额外的时间来实施简短的自定义代码,或提供关于如何实施自定义项目的详细技术信息,以便商家如果决定聘请专门的 WooCommerce 开发者,可以更快地找到解决方案。 即使是 небольшое усилие может оказать большое влияние на удовлетворенность клиентов и создать возможности для请求 5 星评价。
- 当支持团队报告 bug 或请求新功能时,请让他们了解情况。 当我们发布新产品版本时,我们始终会考虑它对支持的影响。
- 与您的支持团队密切合作。 例如,可以考虑每月举行一次反馈会议,讨论产品反馈和计划的改进。
通过采取这些措施,支持团队更愿意与我们分享反馈、问题、疑虑和问题。 这有助于我们与商家建立更紧密的联系,并在问题成为他们流失的原因之前,尽早发现并解决问题。
何时请求 WooCommerce 扩展的评论
提高我们的五星级评论的最佳方法是,识别出商家旅程中的关键时刻,即他们更有可能留下评论,并主动请求他们留下评论。
对于大多数用例,最明显的时刻是:
- 当商家感到无助、迷茫或沮丧,而我们能够提供帮助时;
- 当商家在我们的代码中发现错误,而我们能够迅速修复时;
- 当商家需要某个功能,而我们通知他们该功能已发布时;
- 当商家感到孤立,而我们让他们感受到被倾听;
- 当商家提出问题,而我们竭尽全力为他们提供一流的支持,即使这意味着稍微超出官方支持政策的范围。
请考虑谁会看到评论请求,以及他们在当时正在做什么。向正在尝试发货订单的订单处理人员显示评论请求,可能效果并不好。
在达到某个里程碑后进行推广效果非常好。我们之前使用过的一些措辞是:“恭喜您完成了第 xx 个销售!我们很高兴 WooPayments 促成了这一里程碑。您是否愿意分享您的体验,并鼓励其他人通过评论我们的扩展?”。
另一种优化评论请求时间的方法是设置一个与使用模式相符的提示。例如,如果您知道大多数商家每天都使用您的扩展,那么您可能比那些商家很少使用的扩展更早地发送评论请求。
SaaS/Connector 扩展需要特别注意正确地请求评分,因为如果没有任何问题,它们最容易被忽略,这会导致评分偏差,无法真实反映扩展的实际情况。
请考虑在每次支持互动结束后收集反馈,尤其是在 WordPress.org 支持论坛上。最大的障碍之一是用户需要登录到 WooCommerce.com (或 WordPress.org),而 WordPress.org 支持论坛提供了一个很好的机会来收集这些评论。通过在公共支持论坛上积极响应并解决问题,用户已经登录并能够立即留下评论(在被请求之后!)。
各种建议和指导
与搜索词直接匹配的贡献者姓名将在 WordPress.org 插件库中获得极高的排名,这意味着如果您的 WordPress.org 用户名以您的业务命名(如果该名称是您插件的搜索词),可能会对竞争插件产生不利影响。
持续的提示和在管理员仪表盘上显示不必要的警报会降低用户体验。
您可以请求移除那些实际上不是反馈的评论。例如,如果评论只是一个简单的支持请求,并且明显放在了错误的位置,则可以考虑移除。即使是带有负面情绪的 1 星评论通常也不会被移除。
回复评论!感谢提供反馈的人,如果需要,承认问题,要求提供更具体的反馈,或者在问题得到解决时提供更新!您的评论是了解您的扩展程序用户的真实想法的重要途径。
让与扩展程序开发密切相关的人员(例如开发者和项目经理)定期查看评论,是确保客户的声音被听到的好方法。1 星评论通常最有价值,只要问题能够被理解和解决(如果需要)。
向用户通报错误修复和功能请求
一个错误或缺失的功能可能会对商家造成重大影响。 堆积的错误或未实现的流行功能可能导致负面评论,以及商家流失并寻找竞争解决方案。
通常,错误会通过支持渠道或 GitHub 报告,或者您可以在测试过程中自行发现。
当发现一个严重错误时,应在几天内解决它(大多数严重错误应在 24 小时内解决),并迅速发布一个新的插件版本。 您的发布流程的一部分应该是通知所有利益相关者(支持团队和受影响的商家)即将发布的版本。
即使一个严重错误给商家带来了很大的压力,但快速的解决能够让商家感到被倾听和被支持。 拥有一个可靠的合作伙伴,尤其是在最困难的情况下愿意提供帮助,有助于建立更牢固的关系。 因此,我们通常会要求商家在交付快速解决方案后给予 5 星的评价。
当您实现一个新的功能请求并发布一个新的插件版本时,您可以遵循与错误修复类似的方法:
- 通知所有利益相关者。
- 在“功能请求”看板中更新相关的请求,通过分享公开的更新并将其标记为“已完成”。
- 对于重大版本发布:与您的市场/公关团队沟通,以便在发布前发布更新/新闻邮件。
如何回应 WooCommerce 扩展的负面评价
商家在旅程中遇到不愉快的事件时,可能会留下公开的负面评价。这些事件通常包括:
- 产品存在问题
- 产品功能缺失
- 回复没有帮助
- 等待回复时间过长
- 或以上情况的组合
收到负面评价时,您的目标始终应该是扭转这一评价——这听起来很困难,但确实非常有价值。
在大多数情况下,留下负面评价的商家首先会尝试联系支持团队寻求帮助。这是一个有用的信息,因为我们可以阅读对话历史,了解商家遇到的问题,并在联系他们时分享更多详情,即使是在我们的首次回复中。
我们观察到的有效流程是:
- 创建新的回复(通过邮件或在公开评价中),主题:关于您最近对 xxx 的评价。
- 首先自我介绍,例如:"您好,我是来自开发 xxx 团队的 Andrew"。
- 使用共情的语言,并明确表示这次负面评价对您产生了影响。例如:"我阅读了您最近对 xxx 的评价,听到问题阻碍了您按预期使用此插件,我感到很担忧。我很乐意帮助您解决这个问题!"。
将上述句子与以下句子进行比较:"很遗憾听说您在 xxx 上遇到了问题"。"很遗憾"表示您对某事件感到难过,但不一定计划为此采取行动。相比之下,在"我很担心听到"中,"担心"暗示了行动。此外,"您在 xxx 上遇到了问题"可能被解读为问题主要是商家的过错,而像"某个问题阻碍了您按预期使用此插件。我很乐意帮助您解决这个问题!"这样的措辞则暗示您和商家站在同一阵线。
- 分享更多详情、解决方案、想法、建议或解释。
- 通过强调评论对我们的团队和其他商家的重要性,敦促商家更新评论。示例措辞为:"如果您能花几分钟时间更新您的评论,描述您对我们产品和支持的体验,我们将不胜感激。诚实的评论对其他尝试决定插件是否适合他们的商家非常有帮助。谢谢您的贡献!"。
- 包含指向评论部分的直接链接,以便商家轻松导航至该处并更改其评论。
- 在后续沟通中,如果商家已更改评论,可以考虑这样说:"我与团队其他成员分享了此事,这让每个人都感到非常高兴"。
如果上述情况属实,与商家分享您的部分流程(强调您的团队如何重视反馈并从中获益)有助于确保商家感觉您是他们的团队一员,并与他们建立牢固的关系。
即使商家没有更改评价,通过更多地了解他们的设置并提供一些建议,也能促成一次互利的讨论。这些对话有助于增进商家对您的信任。
如何利用您的支持团队来响应反馈
您的支持团队通常是商家与您联系的主要入口。门票(Tickets)和聊天是与商家沟通的最佳工具,可以帮助我们了解他们对软件的使用情况,倾听他们的反馈,并分析他们的功能请求。 总体而言,支持团队对产品以及用户的使用方式有着深刻的理解。 这些信息对于传递给产品和工程团队至关重要。
我们建议您采取以下步骤,以最佳方式利用您的支持团队:
- 创建严格的内部服务级别协议 (SLA),确保支持团队的请求由产品或工程团队来解答。
- 确保您的支持团队能够有效地向产品和工程团队报告 bug。
- 在回复您的支持团队时,避免使用过于简短的回答,并尝试用简单明了的语言解释答案。 这样可以让支持人员将您的答案复制/粘贴给商家。
- 避免直接回复“不可能”或“该功能不会实现”之类的语句,而应提供有关技术或产品限制的更多上下文信息。
- 定期抽出额外的时间来实施简短的自定义代码,或提供关于如何实施自定义项目的详细技术信息,以便商家如果决定聘请专门的 WooCommerce 开发者,可以更快地找到解决方案。 即使是 небольшое усилие может оказать большое влияние на удовлетворенность клиентов и создать возможности для请求 5 星评价。
- 当支持团队报告 bug 或请求新功能时,请让他们了解情况。 当我们发布新产品版本时,我们始终会考虑它对支持的影响。
- 与您的支持团队密切合作。 例如,可以考虑每月举行一次反馈会议,讨论产品反馈和计划的改进。
通过采取这些措施,支持团队更愿意与我们分享反馈、问题、疑虑和问题。 这有助于我们与商家建立更紧密的联系,并在问题成为他们流失的原因之前,尽早发现并解决问题。
何时请求 WooCommerce 扩展的评论
提高我们的五星级评论的最佳方法是,识别出商家旅程中的关键时刻,即他们更有可能留下评论,并主动请求他们留下评论。
对于大多数用例,最明显的时刻是:
- 当商家感到无助、迷茫或沮丧,而我们能够提供帮助时;
- 当商家在我们的代码中发现错误,而我们能够迅速修复时;
- 当商家需要某个功能,而我们通知他们该功能已发布时;
- 当商家感到孤立,而我们让他们感受到被倾听;
- 当商家提出问题,而我们竭尽全力为他们提供一流的支持,即使这意味着稍微超出官方支持政策的范围。
请考虑谁会看到评论请求,以及他们在当时正在做什么。向正在尝试发货订单的订单处理人员显示评论请求,可能效果并不好。
在达到某个里程碑后进行推广效果非常好。我们之前使用过的一些措辞是:“恭喜您完成了第 xx 个销售!我们很高兴 WooPayments 促成了这一里程碑。您是否愿意分享您的体验,并鼓励其他人通过评论我们的扩展?”。
另一种优化评论请求时间的方法是设置一个与使用模式相符的提示。例如,如果您知道大多数商家每天都使用您的扩展,那么您可能比那些商家很少使用的扩展更早地发送评论请求。
SaaS/Connector 扩展需要特别注意正确地请求评分,因为如果没有任何问题,它们最容易被忽略,这会导致评分偏差,无法真实反映扩展的实际情况。
请考虑在每次支持互动结束后收集反馈,尤其是在 WordPress.org 支持论坛上。最大的障碍之一是用户需要登录到 WooCommerce.com (或 WordPress.org),而 WordPress.org 支持论坛提供了一个很好的机会来收集这些评论。通过在公共支持论坛上积极响应并解决问题,用户已经登录并能够立即留下评论(在被请求之后!)。
如何防止 WooCommerce 网站的数据泄露
数据泄露可能会暴露敏感信息,并危及 WooCommerce 网站的安全性。 数据泄露的一个常见来源是直接访问 PHP 文件。 本教程将向您展示如何防止此类数据泄露。
在您 WooCommerce 扩展的每个 PHP 文件中,您应该检查是否定义了一个名为 'ABSPATH' 的常量。 此常量由 WordPress 本身定义,如果文件被直接访问,则不会定义该常量。 以下是如何操作:
if ( ! defined( 'ABSPATH' ) ) {
exit; // 如果被直接访问,则退出
}
通过这段代码,如果有人尝试直接访问 PHP 文件,'ABSPATH' 常量将未定义,并且脚本将在任何敏感数据泄露之前退出。
请记住,安全性是任何 WooCommerce 网站的一个至关重要的方面。 始终采取措施防止数据泄露并保护您网站的信息。
WooCommerce 安全最佳实践
安全实践简介
安全性对于在线商店至关重要。安全漏洞可能导致严重的财务损失、声誉损害以及客户信任的丧失。实施强大的安全措施至关重要。本指南涵盖了保护 WooCommerce 商店的最佳实践,包括加固 WordPress 系统、保持插件和主题的更新、实施安全的编码实践以及保护用户数据。通过遵循这些建议,开发者可以构建安全且具有弹性的 WooCommerce 商店,从而保护他们的业务和客户。
目标读者
本指南面向熟悉 WordPress 和 WooCommerce 并且希望提高其在线商店安全性的开发者。
前置条件
要遵循本指南,您应该具备以下条件:
- 对 WordPress 和 WooCommerce 有基本的了解。
- 拥有已安装并启用的 WooCommerce 的 WordPress 网站的访问权限。
安全标准
我们建议您维护以下标准:
-
PHPCS: PHP 代码检查工具可以帮助确保您的代码符合特定的编码标准,从而可以防止常见的安全问题。扩展程序不应在 PHPCS 检查中出现任何失败的结果。
-
SemGrep: 专注于识别可能表明安全漏洞的模式,从而允许开发者编写更安全的代码。扩展程序不应在 SemGrep 检查中出现任何失败的结果。
理解和实施这些标准可以显著降低扩展程序和主题中安全漏洞的风险。
常见的安全陷阱以及如何避免
以下是一些常见的安全陷阱,可以通过谨慎和最佳实践轻松避免:
- SQL 注入: 确保所有数据库查询都经过适当的清理。
- 跨站脚本攻击: 清理所有用户输入,以防止恶意代码被执行。
- 文件包含: 限制文件包含,以防止未经授权的访问文件系统。
了解和预防这些常见问题是保护您的 WooCommerce 商店的关键步骤。 欲了解更多信息,我们建议您阅读 WordPress 安全文档。
手动测试指南
即使没有访问像 Woo Quality Insights Toolkit (QIT) 这样的自动化工具,手动测试仍然是确保您的 WooCommerce 商店安全的重要组成部分。以下是一些关于开发者如何手动测试其扩展程序以查找安全漏洞的指南:
- 代码审查: 定期审查您的代码是否存在安全漏洞,重点关注容易发生漏洞的区域,例如用户输入字段和数据库查询。代码审查应参考上述 WordPress 安全标准。
- 使用安全插件: 像 Wordfence、Sucuri 或 iThemes Security 这样的插件提供了一个界面,用于进行手动安全检查,包括文件完整性监控和恶意软件扫描。此外,可以使用诸如 OWASP Zap 或 GitHub Security Scanning 这样的工具。
- 测试环境: 使用测试环境来测试新功能或更新的安全性,然后再将其部署到生产环境。
其他安全最佳实践
保持 WordPress、WooCommerce 和插件的更新
定期更新 WordPress、WooCommerce 和所有已安装的插件对于维护安全的在线商店至关重要。更新通常包含安全补丁,可以解决漏洞并帮助保护您的商店免受攻击。要保持您的 WordPress 和 WooCommerce 安装的最新状态:
- 启用 WordPress 核心的自动更新。
- 定期检查并安装 WooCommerce 和所有插件的更新。
选择安全的插件和主题
您使用的插件和主题会对您的 WooCommerce 商店的安全性产生重大影响。为了确保您的商店安全:
- 从信誉良好的来源安装插件和主题,例如 WordPress 插件目录和主题目录。
- 定期审查和更新您使用的插件和主题,删除任何不再维护或已知存在安全漏洞的插件和主题。
- 避免使用盗版或破解的插件和主题,因为它们可能包含恶意代码。
实施安全的编码实践
安全的编码实践对于构建安全的 WooCommerce 商店至关重要。为了实施安全的编码实践:
- 在开发自定义主题或插件时,请遵循 WordPress 编码标准。
- 使用预处理语句和参数化查询来防止 SQL 注入攻击。
- 验证和清理用户输入,以防止跨站脚本攻击 (XSS) 和其他漏洞。
- 定期审查和更新您的自定义代码,以解决潜在的安全漏洞。
加强 WordPress 安全性
加强您的 WordPress 安装可以帮助保护您的 WooCommerce 商店免受攻击。 要加强 WordPress 的安全性:
- 为所有用户帐户使用强密码。
- 限制登录尝试,并启用双因素身份验证 (2FA),以防止暴力破解攻击。
- 更改 WordPress 数据库中默认的
wp_表前缀。 - 在不需要时禁用 XML-RPC 和 REST API 访问。
- 保持文件权限安全,并限制对敏感文件和目录的访问。
保护用户数据
保护客户的数据是确保 WooCommerce 商店安全的关键方面。 要保护用户数据:
- 使用 SSL 证书来加密您商店和客户之间传输的数据。
- 安全地存储客户数据,并限制对敏感信息的访问。
- 遵守数据保护法规,例如 GDPR,以确保您负责地处理客户数据。
实施安全插件
使用安全插件可以帮助您监控和保护您的 WooCommerce 商店免受潜在威胁。 要实施安全插件:
- 选择一个信誉良好的安全插件,例如 Wordfence、Sucuri 或 iThemes Security。
- 配置插件的设置,以启用诸如恶意软件扫描、防火墙保护和登录安全等功能。
定期监控和审计您的商店安全
持续监控和审计您的 WooCommerce 商店的安全,以识别潜在的漏洞,并在它们被利用之前解决它们。 要监控和审计您的商店安全:
- 使用安全插件定期扫描恶意软件和其他安全威胁。
- 监控您站点的活动日志,以识别可疑活动和潜在的安全问题。
- 定期进行安全审计,以评估您商店的整体安全性,并确定需要改进的方面。
创建定期备份
备份您的 WooCommerce 商店对于快速恢复安全事件至关重要,例如数据丢失或网站被入侵。 要创建定期备份:
- 选择一个可靠的备份插件,例如 UpdraftPlus、BackupBuddy 或 Duplicator。
- 配置插件以自动定期备份您的整个站点,包括数据库、文件和媒体。
- 将您的备份安全地存储在异地,以确保在发生紧急情况时可以访问它们。
结论
通过遵循这些安全最佳实践,您可以构建一个安全且具有弹性的 WooCommerce 商店,该商店可以保护您的业务和您的客户。 定期监控、审计和更新您商店的安全措施,将有助于确保它在出现新的威胁和漏洞时仍然受到保护。
如何防止 WooCommerce 网站的数据泄露
数据泄露可能会暴露敏感信息,并危及 WooCommerce 网站的安全性。 数据泄露的一个常见来源是直接访问 PHP 文件。 本教程将向您展示如何防止此类数据泄露。
在您 WooCommerce 扩展的每个 PHP 文件中,您应该检查是否定义了一个名为 'ABSPATH' 的常量。 此常量由 WordPress 本身定义,如果文件被直接访问,则不会定义该常量。 以下是如何操作:
if ( ! defined( 'ABSPATH' ) ) {
exit; // 如果被直接访问,则退出
}
通过这段代码,如果有人尝试直接访问 PHP 文件,'ABSPATH' 常量将未定义,并且脚本将在任何敏感数据泄露之前退出。
请记住,安全性是任何 WooCommerce 网站的一个至关重要的方面。 始终采取措施防止数据泄露并保护您网站的信息。
可分享的结账链接
自定义结账链接会自动将特定产品添加到购物车,并将客户直接重定向到带有唯一会话 ID 的结账页面。
自定义结账链接的路径是 /checkout-link/,且不可自定义。
支持的参数
产品
products=123:2,456:1
产品 ID 和数量的逗号分隔列表。例如:123:2,456:1。此功能支持没有额外选项的简单产品。也可以通过使用正确的变体 ID 将单个变体添加到购物车。
优惠券
coupon=SPRING10
应用于购物车的优惠券代码。例如:SPRING10。
示例
https://yourstore.com/checkout-link/?products=123:2,456:1&coupon=SPRING10
在这个链接中:
- 产品 ID
123将以数量2添加到购物车 - 产品 ID
456将以数量1添加到购物车 - 将应用优惠券代码
SPRING10 - 客户将被直接带到结账页面
会话
当用户被重定向到结账页面时,购物车将被填充产品和优惠券代码。最终的 URL 包含一个 session 参数,用于存储会话 ID。对结账的后续更改将保存在会话中,从而实现持久且可共享的购物车。
自定义 WooCommerce 端点 URL
在开始之前,请查看 WooCommerce 端点。
自定义端点 URL
每个端点的 URL 可以在 WooCommerce > 设置 > 高级 的“页面设置”部分进行自定义。

请确保它们是唯一的,以避免冲突。 如果遇到 404 错误,请转到 设置 > 固定链接 并保存以刷新重写规则。
在菜单中使用端点
如果您想在菜单中包含一个端点,则需要使用“链接”部分:

输入端点的完整 URL,然后将其插入到您的菜单中。
请记住,某些端点,例如 view-order,需要一个订单 ID 才能正常工作。 通常,我们不建议将这些端点添加到您的菜单中。 这些页面可以通过“我的账户”页面访问。
在支付网关插件中使用端点
WooCommerce 在订单类中提供了辅助函数,用于获取这些 URL。 它们是:
$order->get_checkout_payment_url( $on_checkout = false );
以及:
$order->get_checkout_order_received_url();
网关需要使用这些方法以获得完整的 2.1+ 兼容性。
故障排除
端点显示 404 错误
- 如果您看到 404 错误,请转到 WordPress 后台 > 设置 > 固定链接 并保存。 这可确保端点的重写规则存在并且已准备就绪。
- 如果使用诸如 view-order 之类的端点,请确保它指定了订单号。 /view-order/ 无效。 /view-order/10/ 有效。 此类端点不应出现在您的导航菜单中。
端点无法正常工作
在 Windows 服务器上,web.config 文件可能未正确设置,无法使端点正常工作。 在这种情况下,单击端点链接(例如 /edit-account/ 或 /customer-logout/)可能似乎什么也没做,只是刷新了页面。 为了解决此问题,请尝试简化 Windows 服务器上的 web.config 文件。 以下是一个示例文件配置:
<<>?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Execute, Script" />
<rewrite>
<rules>
<rule name="wordpress" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
网页跳转到错误的位置
当点击某个端点 URL 时,如果跳转到错误的网页,通常是由于设置不正确造成的。例如,如果在您的账户页面点击“编辑地址”,但跳转到了商店页面,而不是编辑地址的表单,这意味着您在设置中选择了错误的网页。请确认您的网页配置是否正确,并且每个部分都使用了不同的网页。
如何从“我的账户”中移除“下载”
有时,“我的账户”页面上的“下载”端点不需要显示。可以通过访问 WooCommerce > 设置 > 高级 > 账户端点,然后清除“下载”端点字段来移除它。

理解在 WooCommerce 中移除 URL 基础部分的风险
总结
移除 /product/、/product-category/ 或 /shop/ 这些基础部分,通常是不建议的,因为这会影响 WordPress 解析 URL 的方式。 WordPress 使用 URL 的 product-category (或者任何其他文本) 基础部分来检测该 URL 是否指向一个产品分类。 某些 SEO 插件允许您移除这些基础部分,但这可能会导致性能问题和重复 URL。
尽量避免
移除这些基础部分会使 WordPress 更难检测您尝试访问的页面。 此外,请理解 WordPress 中标准的 "网页" 始终在 URL 中不包含任何基础文本。 例如:
http://yoursite.com/about-page/(这是标准网页的 URL)http://yoursite.com/product-category/category-x/(这是指向产品分类的 URL)
如果我们移除 "product-category" 部分会发生什么?
http://yoursite.com/about-page/http://yoursite.com/category-x/
在这种情况下,WordPress 需要付出更多努力才能检测您正在寻找的页面。 这就是为什么我们不建议使用任何 SEO 插件来实现此目的。
在 WooCommerce 中使用 Webhook
什么是 Webhook?
一个 Webhook 是一种事件通知,发送到您选择的 URL。 用户可以配置它们,以便在一个站点的事件触发另一个站点的行为。
Webhook 对于与第三方服务和其他支持它们的外部 API 集成非常有用。
WooCommerce 中的 Webhook
Webhook 在 WooCommerce 2.2 中引入,可以在您添加、编辑或删除订单、产品、优惠券或客户时触发事件。
您还可以使用 Webhook 与 WooCommerce 的操作结合使用,例如,创建一个 Webhook,以便在每次将产品添加到购物车时触发,使用操作 woocommerce_add_to_cart。
Webhook 还可以使第三方应用程序更容易与 WooCommerce 集成。
创建 Webhook

要创建新的 Webhook:
1/ 转到: WooCommerce > 设置 > 高级 > Webhook。
注意: 在 WooCommerce 3.4 之前,Webhook 位于 WooCommerce > 设置 > API 下。
2/ 选择 创建新的 Webhook (首次创建) 或 添加 Webhook。 Webhook 数据 框将出现。

3/ 输入:
- 名称: 名称 会自动生成为 "Webhook created on [创建日期和时间]",作为标准,以方便创建。 将名称更改为其他名称。
- 状态: 设置为 活动 (发送数据),暂停 (不发送数据),或 禁用 (由于发送失败而不会发送数据)。
- 主题: 指示何时触发 Webhook - 订单创建,产品删除,或 客户更新。 还有 操作 和 自定义 选项。
- 操作事件: 当主题是 WooCommerce 操作 时,此选项可用,例如
woocommerce_add_to_cart,表示当客户将产品添加到购物车时。 - 自定义主题: 此选项仅适用于 高级用户。 您可以使用
woocommerce_webhook_topic_hooks过滤器引入新的、自定义的主题。
- 操作事件: 当主题是 WooCommerce 操作 时,此选项可用,例如
- 传递 URL: Webhook 数据传递到的 URL。
- 密钥: 密钥生成传递的 Webhook 的哈希值,并在请求头中提供。 如果未输入任何内容,则默认为当前 API 用户的消费者密钥。
4/ 保存 Webhook。
注意: 首次以“已激活”状态保存 Webhook 时,它会将一个 ping 发送到传递 URL。
如果传递 URL 返回不成功的状态,例如 404 或 5xx,Webhook 默认情况下会尝试 5 次后被禁用。 成功的响应是 2xx、301 或 302。
要增加重试次数,可以使用 woocommerce_max_webhook_delivery_failures 过滤器函数。
编辑和删除 Webhook
Webhook 的显示方式与帖子或产品相同。
- 查找 您想要修改的 Webhook。
- 将鼠标悬停在名称上,会显示 编辑 和 永久删除 选项。
- 删除,或进行 编辑 并 保存 修改。 还可以通过下拉菜单进行批量删除。

Webhook 日志
WooCommerce 会保存所有触发 Webhook 的事件的日志。 Webhook 日志位于:WooCommerce > 状态 > 日志。

可以查看日志以了解服务器的响应和状态,这有助于简化集成和 调试。
理解 WooCommerce 端点
端点是在网站 URL 中的附加部分,当存在时,会被识别出来以显示不同的内容。
例如:您可能在 URL yoursite.com/my-account 上显示一个“我的账户”网页。当将端点 'edit-account' 添加到此 URL,使其变为 'yoursite.com/my-account/edit-account' 时,则会显示 编辑账户页面,而不是 我的账户页面。
这允许我们在无需多个网页和短代码的情况下显示不同的内容,并减少需要安装的内容量。
端点位于 WooCommerce > 设置 > 高级。
结账端点
以下端点用于与结账相关的功能,并附加到 /checkout 页面的 URL:
- 支付页面 -
/order-pay/{ORDER_ID} - 订单已收到(感谢)-
/order-received/ - 添加付款方式 -
/add-payment-method/ - 删除付款方式 -
/delete-payment-method/ - 设置默认付款方式 -
/set-default-payment-method/
账户端点
以下端点用于与账户相关的功能,并附加到 /my-account 页面的 URL:
- 订单 -
/orders/ - 查看订单 -
/view-order/{ORDER_ID} - 下载 -
/downloads/ - 编辑账户(和更改密码)-
/edit-account/ - 地址 -
/edit-address/ - 付款方式 -
/payment-methods/ - 忘记密码 -
/lost-password/ - 退出 -
/customer-logout/
了解更多
理解在 WooCommerce 中移除 URL 基础部分的风险
总结
移除 /product/、/product-category/ 或 /shop/ 这些基础部分,通常是不建议的,因为这会影响 WordPress 解析 URL 的方式。 WordPress 使用 URL 的 product-category (或者任何其他文本) 基础部分来检测该 URL 是否指向一个产品分类。 某些 SEO 插件允许您移除这些基础部分,但这可能会导致性能问题和重复 URL。
尽量避免
移除这些基础部分会使 WordPress 更难检测您尝试访问的页面。 此外,请理解 WordPress 中标准的 "网页" 始终在 URL 中不包含任何基础文本。 例如:
http://yoursite.com/about-page/(这是标准网页的 URL)http://yoursite.com/product-category/category-x/(这是指向产品分类的 URL)
如果我们移除 "product-category" 部分会发生什么?
http://yoursite.com/about-page/http://yoursite.com/category-x/
在这种情况下,WordPress 需要付出更多努力才能检测您正在寻找的页面。 这就是为什么我们不建议使用任何 SEO 插件来实现此目的。
附加结账字段
对于开发者和商家来说,一个常见的用例是向结账表单添加新的字段,以收集有关客户或其订单的更多信息。
本文档将概述扩展程序应采取的步骤,以注册一些附加的结账字段。
可用的字段位置
附加的结账字段可以在三个不同的位置进行注册:
| 标题 | 标识符 |
|---|---|
| 联系信息 | contact |
| 地址(配送 和 账单) | address |
| 订单信息 | order |
一个字段只能显示在一个位置,在同一个注册中,无法在多个位置渲染相同的字段。
联系信息
联系信息部分当前位于表单的顶部。它包含 email 字段以及任何其他附加字段。
在此处渲染的字段将保存到购物者的帐户中。它们将在购物者的“帐户详情”部分可见和可编辑。
地址
“地址”部分当前包含一个用于配送地址和账单地址的表单。可以注册附加的结账字段,使其出现在这些表单中。
在此处注册的字段将同时保存到客户 和 订单中,因此回头客无需再次填写这些值。
如果在 address 位置注册了一个字段,它将同时出现在配送地址和账单地址中。 不可能将该字段仅显示在其中一个地址中。
您最终将为该字段收集两个值,一个用于配送,一个用于账单。
订单信息
作为“额外结账字段”功能的一部分,结账阻止块现在包含一个名为“订单信息阻止块”的新内部阻止块。
此阻止块用于渲染不属于联系信息或地址信息的部分,例如,它可能是一个“您是通过什么途径了解我们的”字段或一个“礼品留言”字段。
在此处渲染的字段将保存到订单中。它们不会成为客户保存的地址或帐户信息的一部分。新订单不会预先填充任何之前使用过的值。
默认情况下,此阻止块将作为结账表单的最后一步显示,但您可以使用古腾堡阻止控件在编辑器中移动它。
访问值
附加字段会分别保存到客户元数据和订单元数据中的独立元键中。您可以使用辅助方法访问它们,也可以直接使用元键。我们建议使用辅助方法,因为它们不太可能发生变化,可以处理未来的迁移,并且将支持未来的增强功能(例如,从不同的位置读取)。
对于地址字段,会保存两个值:一个用于配送,一个用于账单。如果客户选择了“使用相同的地址用于账单”,则这些值将相同,但仍然独立保存。
对于联系信息和订单字段,每个字段只保存一个值。
辅助方法
CheckoutFields 提供了一个函数用于访问客户和订单中的值,该函数是 get_field_from_object。
要访问客户的账单和/或配送信息:
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
$field_id = 'my-plugin-namespace/my-field';
$customer = wc()->customer; // 或者 new WC_Customer( $id )
$checkout_fields = Package::container()->get( CheckoutFields::class );
$my_customer_billing_field = $checkout_fields->get_field_from_object( $field_id, $customer, 'billing' );
$my_customer_shipping_field = $checkout_fields->get_field_from_object( $field_id, $customer, 'shipping' );
要访问订单字段:
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
$field_id = 'my-plugin-namespace/my-field';
$order = wc_get_order( 1234 );
$checkout_fields = Package::container()->get( CheckoutFields::class );
$my_order_billing_field = $checkout_fields->get_field_from_object( $field_id, $order, 'billing' );
$my_order_shipping_field = $checkout_fields->get_field_from_object( $field_id, $order, 'shipping' );
在订单提交后,保存到客户的数据和保存到订单的数据将是相同的。 客户可以更改_未来_订单的值,或者在他们的“我的账户”网页中进行更改。 如果您在特定时间点查看客户数据(例如,在订单提交时),请从订单对象中访问它;如果您需要获取最新的数据,请从客户对象中访问它。
访客客户
当访客客户提交包含附加字段的订单时,这些字段将保存到其会话中,因此只要客户仍然有有效的会话,这些值始终可用。
已登录的客户
对于已登录的客户,值只有在他们提交订单后才会持久保存。 在订单提交生命周期中访问已登录的客户对象将返回 null 或过时的数据。
如果在订单提交钩子中执行以下操作,将返回以前的数据(而不是当前插入的数据):
$customer = new WC_Customer( $order->customer_id ); // 或者 new WC_Customer( 1234 )
$my_customer_billing_field = $checkout_fields->get_field_from_object( $field_id, $customer, 'billing' );
相反,如果您想执行一些额外的验证/数据移动,请始终访问最新的数据:
$customer = wc()->customer // 这将返回具有其会话的当前客户。
$my_customer_billing_field = $checkout_fields->get_field_from_object( $field_id, $customer, 'billing' );
访问所有字段
您可以使用 get_all_fields_from_object 函数来访问保存到订单或客户对象上的所有附加字段。
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
$order = wc_get_order( 1234 );
$checkout_fields = Package::container()->get( CheckoutFields::class );
$order_additional_billing_fields = $checkout_fields->get_all_fields_from_object( $order, 'billing' );
$order_additional_shipping_fields = $checkout_fields->get_all_fields_from_object( $order, 'shipping' );
$order_other_additional_fields = $checkout_fields->get_all_fields_from_object( $order, 'other' ); // 联络信息和订单信息都保存在附加组中的同一位置。
这将返回一个包含所有值的数组。 默认情况下,它只包含当前注册的字段。 如果您想包含不再注册的字段,可以传递一个第三个 true 参数。
$order = wc_get_order( 1234 );
$checkout_fields = Package::container()->get( CheckoutFields::class );
$order_additional_billing_fields = $checkout_fields->get_all_fields_from_object( $order, 'billing' ); // array( 'my-plugin-namespace/my-field' => 'my-value' );
$order_additional_billing_fields = $checkout_fields->get_all_fields_from_object( $order, 'billing', true ); // array( 'my-plugin-namespace/my-field' => 'my-value', 'old-namespace/old-key' => 'old-value' );
直接访问值
虽然不推荐,但您可以使用直接的元键来访问某些值。 这对于外部引擎或仅提供对元值访问的页面/电子邮件构建器非常有用。
值保存在预定义的%prefix%下,这是为了能够查询字段,而无需知道该字段在哪个 ID 下注册。 对于键为 'my-plugin-namespace/my-field' 的字段,如果它是%address%,其元键将是以下内容:
_wc_billing/my-plugin-namespace/my-field_wc_shipping/my-plugin-namespace/my-field
或者,如果它是%contact%/订单字段,则为以下内容:
_wc_other/my-plugin-namespace/my-field。
这些%prefix%是 %CheckoutFields% 类的一部分,可以使用以下常量访问:
echo ( CheckoutFields::BILLING_FIELDS_PREFIX ); // _wc_billing/
echo ( CheckoutFields::SHIPPING_FIELDS_PREFIX ); // _wc_shipping/
echo ( CheckoutFields::OTHER_FIELDS_PREFIX ); // _wc_other/
%CheckoutFields% 提供了一些辅助函数,用于根据组名或键来获取组名或键:
CheckoutFields::get_group_name( "_wc_billing" ); // "billing"
CheckoutFields::get_group_name( "_wc_billing/" ); // "billing"
CheckoutFields::get_group_key( "shipping" ); // "_wc_shipping/"
用例是构建键名以直接访问元数据:
$key = CheckoutFields::get_group_key( "other" ) . 'my-plugin/is-opt-in';
$opted_in = get_user_meta( 123, $key, true ) === "1" ? true : false;
复选框的值
当直接访问复选框的值时,它将返回 "1" 表示真,"0" 表示假,或者如果值不存在则返回 ""。 只有提供的函数才能将其转换为布尔值。
支持的字段类型
以下字段类型受支持:
selecttextcheckbox
计划扩展此列表,但目前这些是可用的类型。
使用 API
要注册额外的结账字段,您必须使用 woocommerce_register_additional_checkout_field 函数。
建议在 woocommerce_init 动作之后运行此函数。
注册函数接受一个选项数组,用于描述您的字段。 某些字段类型需要额外的选项。
选项
常规设置
这些选项适用于所有字段类型(除非在少数情况下,具体情况会在“选项”中注明)。
字段配置
本节描述了如何配置字段。
| 选项名称 | 描述 | 是否必填 | 示例 | 默认值 |
|---|---|---|---|---|
id |
字段的 ID。这应该为您的字段提供唯一的标识符。它由命名空间和字段名称组成,中间用 / 分隔。 |
是 | plugin-namespace/how-did-you-hear |
无默认值 - 必须提供。 |
label |
在您的字段上显示的标签。这将也是占位符。 | 是 | How did you hear about us? |
无默认值 - 必须提供。 |
optionalLabel |
如果字段是可选的,则在您的字段上显示的标签。这将也是占位符。 | 否 | How did you hear about us? (Optional) |
默认值将是 label 的值,并在其后附加 (optional)。 |
location |
字段的渲染位置。 | 是 | contact, address, 或 order |
无默认值 - 必须提供。 |
type |
您要渲染的字段类型。默认为 text,并且必须与受支持的字段类型之一匹配。 |
否 | text, select, 或 checkbox |
text |
attributes |
要在字段的输入元素上渲染的附加属性的数组。这_不支持_ select 字段。 |
否 | [ 'data-custom-data' => 'my-custom-data' ] |
[] |
required |
可以是布尔值或 JSON 结构化数据 数组。如果为布尔值且为 true,则购物者 必须 在结账过程中为该字段提供值。对于复选框字段,购物者必须选中复选框才能完成订单。如果为 JSON 结构化数据 数组,则该字段是否必填取决于结构化数据的条件。请参阅 通过 JSON 结构化数据 实现条件可见性和验证。 |
否 | true 或 ["type" => "object", "properties" => [...]] |
false |
hidden |
可以是布尔值或 JSON 结构化数据 数组。如果用作布尔值,则必须为 false。如果为 JSON 结构化数据 数组,则该字段是否隐藏取决于结构化数据的条件。请参阅 通过 JSON 结构化数据 实现条件可见性和验证。 |
否 | false 或 ["type" => "object", "properties" => [...]] |
false |
validation |
定义字段验证规则的 JSON 结构化数据 对象的数组。请参阅 通过 JSON 结构化数据 实现条件可见性和验证。 | 否 | [{"type": "object", "properties": {...}}] |
[] |
sanitize_callback |
在发布时,用于清理客户提供的值的函数。 | 否 | 参见下面的示例 | 默认情况下,字段的值会不作更改地返回。 |
validate_callback |
在发布时,用于验证客户提供的值的函数。这在清理之后运行。 | 否 | 参见下面的示例 | 默认验证函数将在字段为必填但没有值时,向响应添加一个错误。 请参阅默认验证函数。 |
##### `sanitize_callback` 函数示例。此函数将从值中删除空格。<!-- omit from toc -->
```php
'sanitize_callback' => function( $field_value ) {
return str_replace( ' ', '', $field_value );
},
validate_callback 函数示例。此函数将检查值是否为电子邮件地址。
'validate_callback' => function( $field_value ) {
if ( ! is_email( $field_value ) ) {
return new WP_Error( 'invalid_alt_email', '请确保您的备用电子邮件地址符合正确的格式。' );
}
},
text 字段的选项
text 字段除了上面列出的常规设置之外,没有其他额外的选项。
select 字段的选项
除了上面列出的选项之外,select 字段还必须使用 options 选项进行注册。这用于指定用户可以从中选择的选项。
select 字段默认情况下不会选择任何值;如果该字段是必填的,则用户必须选择一个值。
您可以通过在注册字段时传递 placeholder 值,来设置在 select 字段中显示的占位符。这将是 select 中的第一个选项,并且如果该字段是必填的,则用户无法选择此选项。
| 选项名称 | 描述 | 必需? | 示例 | 默认值 |
|---|---|---|---|---|
options |
用于在 select 输入框中显示的选项数组。每个选项必须是一个包含 label 和 value 属性的数组。每个条目必须具有唯一的 value。任何重复的选项将被删除。value 是在结账过程中提交到服务器的值,而 label 只是此值的用户友好表示,它不会以任何方式传输到服务器。 |
是 | 参见下文 | 无默认值 - 必须提供。 |
placeholder |
如果设置了此值,则用户将在 select 中看到此选项。如果 select 是必填的,则用户无法选择此选项。 |
否 | 选择一个角色 |
Select a $label |
options 值的示例
[
[
'value' => 'store_1',
'label' => '我们的伦敦店'
],
[
'value' => 'store_2',
'label' => '我们的巴黎店'
],
[
'value' => 'store_3',
'label' => '我们的纽约店'
]
]
checkbox 字段的选项
除了上面列出的选项之外,checkbox 字段还支持在必填时,如果未选中,则显示错误信息。
| 选项名称 | 描述 | 必需? | 示例 | 默认值 |
|---|---|---|---|---|
error_message |
如果复选框未选中,则显示的自定义消息。 | 否 | 您必须确认您已满 18 岁才能下单。 |
如果希望继续,请选中此框。 |
### 属性
支持为复选框和文本字段添加额外的属性。但是,**目前无法**将属性添加到选择字段。
这些属性与 `input` 元素的 HTML 属性一一对应(`pattern` 属性除外,复选框不支持)。
支持的属性包括:
- `data-*` 属性
- `aria-*` 属性
- `autocomplete`
- `autocapitalize`
- `pattern` (复选框字段不支持)
- `title`
- `maxLength` (等同于 HTML 属性 `maxlength`)
- `readOnly` (等同于 HTML 属性 `readonly`)
`maxLength` 和 `readOnly` 使用驼峰命名法,因为这些属性会渲染到 React 元素上,必须以这种格式接收。
某些属性有意不传递给字段,这些是 `autofocus` 和 `disabled`。我们欢迎接收反馈,并在提供有效的用例时调整此行为。
## 使用示例
### 渲染文本字段
此示例演示如何在地址部分渲染文本字段:
```php
add_action(
'woocommerce_init',
function() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'namespace/gov-id',
'label' => 'Government ID',
'optionalLabel' => 'Government ID (optional)',
'location' => 'address',
'required' => true,
'attributes' => array(
'autocomplete' => 'government-id',
'aria-describedby' => 'some-element',
'aria-label' => 'custom aria label',
'pattern' => '[A-Z0-9]{5}', // 5 个大写字母和数字组成的字符串。
'title' => 'Title to show on hover',
'data-custom' => 'custom data',
),
),
);
}
);
这将在地址表单中生成以下内容(账单表单与此相同):
生成的 HTML 标记如下:
<input type="text" id="shipping-namespace-gov-id" autocapitalize="off"
autocomplete="government-id" aria-label="custom aria label"
aria-describedby="some-element" required="" aria-invalid="true"
title="Title to show on hover" pattern="[A-Z0-9]{5}"
data-custom="custom data" value="">
渲染复选框字段
这个示例演示了如何在联系信息部分渲染一个复选框字段:
add_action(
'woocommerce_init',
function() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'namespace/marketing-opt-in',
'label' => '您是否想订阅我们的新闻通讯?',
'location' => 'contact',
'type' => 'checkbox',
)
);
}
);
这将在联系信息部分显示以下内容:
请注意,由于没有提供 optionalLabel,因此字符串 (optional) 会附加到标签中。要删除该字符串,应提供 optionalLabel 属性以覆盖此行为。
渲染选择字段
这个示例演示了如何在订单信息部分渲染一个选择字段:
add_action(
'woocommerce_init',
function() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'namespace/how-did-you-hear-about-us',
'label' => '您是通过什么途径了解我们的?',
'placeholder' => '选择一个来源',
'location' => 'order',
'type' => 'select',
'options' => [
[
'value' => 'google',
'label' => 'Google'
],
[
'value' => 'facebook',
'label' => 'Facebook'
],
[
'value' => 'friend',
'label' => '朋友推荐'
],
[
'value' => 'other',
'label' => '其他'
],
]
)
);
}
);
这将在订单信息部分以如下方式进行渲染:
获得焦点之前的选择输入框
获得焦点时的选择输入框
如果不想强制用户选择一个值,可以通过将 required 选项设置为 false,将选择框标记为可选。
验证和清理
可以使用 WordPress 动作钩子,为附加的结账字段添加自定义的验证和清理功能。
这些操作发生在两个地方:
- 在结账过程中更新和提交表单,以及
- 在“我的账户”区域更新地址/联系信息。
清理
清理用于确保字段的值具有特定的格式。例如,在获取政府身份证件时,您可能希望将其格式化为所有字母大写且没有空格。此时,不应检查该值的 有效性。这将在稍后进行。此步骤仅用于为验证做好准备。
使用 woocommerce_sanitize_additional_field 过滤器
为了运行自定义的字段清理函数,您可以在注册时使用 sanitize_callback 函数,或者使用 woocommerce_sanitize_additional_field 过滤器。
| 参数 | 类型 | 描述 |
|---|---|---|
$field_value |
boolean|string |
字段的值。 |
$field_key |
string |
字段的 ID。 这与字段注册时使用的 ID 相同。 |
清理示例
此示例展示了如何移除空格并将所有字母转换为大写,以清理我们在上面添加的“政府 ID”示例字段。
add_action(
'woocommerce_sanitize_additional_field',
function ( $field_value, $field_key ) {
if ( 'namespace/gov-id' === $field_key ) {
$field_value = str_replace( ' ', '', $field_value );
$field_value = strtoupper( $field_value );
}
return $field_value;
},
10,
2
);
验证
在附加的结账字段系统中,有两个验证阶段。 第一个阶段是根据字段的键和值验证单个字段。
单个字段验证
使用 woocommerce_validate_additional_field 动作
当 woocommerce_validate_additional_field 动作被触发时,回调函数会接收到字段的键、字段的值以及一个 WP_Error 对象。
要将验证错误添加到响应中,请使用 WP_Error::add 方法。
| 参数 | 类型 | 描述
WP_Error 对象
当您向 WP_Error 对象添加错误时,该错误应该具有唯一的错误代码。 您可能希望在错误代码前添加插件命名空间,以减少冲突的可能性。 使用其他插件中已使用的代码可能会导致错误信息被覆盖或显示在不同的位置。
单个字段验证示例
以下示例展示了如何将自定义验证应用于上述 namespace/gov-id 文本字段。 此处的代码确保该字段由 5 个字符组成,可以是大写字母或数字。 上述示例中的 sanitization 函数确保删除所有空格并将所有字母大写,因此此检查是额外的安全措施,以确保输入与模式匹配。
add_action(
'woocommerce_validate_additional_field',
function ( WP_Error $errors, $field_key, $field_value ) {
if ( 'namespace/gov-id' === $field_key ) {
$match = preg_match( '/[A-Z0-9]{5}/', $field_value );
if ( 0 === $match || false === $match ) {
$errors->add( 'invalid_gov_id', '请确保您的政府 ID 符合正确的格式。' );
}
}
},
10,
3
);
重要的是要注意,此操作必须向它接收到的 WP_Error 对象 添加 错误。 返回一个新的 WP_Error 对象或任何其他值会导致错误不显示。
如果没有遇到任何验证错误,该函数可以直接返回 void。
多个字段验证
在某些情况下,一个字段的有效性取决于另一个字段的值,例如,根据购物者所在的国家/地区来验证政府 ID 的格式。 在这种情况下,仅验证单个字段(如上所示)是不够的,因为在 woocommerce_validate_additional_field 操作期间,国家/地区可能未知。
为了解决这个问题,可以在字段呈现的上下文环境中验证该字段。 位于该位置的其他字段将传递给此操作。
使用 woocommerce_blocks_validate_location_{location}_fields 动作
此动作将为每个可以渲染附加字段的位置(address、contact 和 order)触发一次。对于 address,它会触发两次,一次是用于账单地址,另一次是用于配送地址。
回调函数接收到相同位置的其他附加字段的键和值。
需要注意的是,在其他位置渲染的任何字段都不会传递给此动作,但是可以通过访问客户或订单对象来获取这些值,但这不受支持,并且未来版本不保证兼容性。
| 参数 | 类型 | 描述 |
|---|---|---|
$errors |
WP_Error |
一个错误对象,包含在处理请求时已经遇到的错误。如果尚未添加任何错误,它仍然是一个 WP_Error 对象,但为空。 |
$fields |
array |
在此位置渲染的字段。 |
$group |
'billing'|'shipping'|'other' |
如果该动作是针对地址位置,则此处会设置地址类型。如果是针对联系方式或订单,则此值为 'other'。 |
这些钩子在以下几个地方会被触发。
- 在使用结账块或 Store API 进行结账时:
woocommerce_blocks_validate_location_address_fields(x2)woocommerce_blocks_validate_location_contact_fieldswoocommerce_blocks_validate_location_other_fields
- 在“我的账户”区域更新地址时:
woocommerce_blocks_validate_location_address_fields(x1 - 仅针对正在编辑的地址)
- 在“我的账户”区域更新“账户详情”部分时:
woocommerce_blocks_validate_location_contact_fields
地址验证示例
在这个示例中,假设除了 namespace/gov-id 之外,还注册了一个名为 namespace/confirm-gov-id 的字段。这个字段将用于确认政府 ID 字段。
下面的示例说明了如何验证确认字段的值是否与主字段的值匹配。
add_action(
'woocommerce_blocks_validate_location_address_fields',
function ( \WP_Error $errors, $fields, $group ) {
if ( $fields['namespace/gov-id'] !== $fields['namespace/confirm-gov-id'] ) {
$errors->add( 'gov_id_mismatch', '请确保您的政府 ID 与确认信息一致。' );
}
},
10,
3
);
如果这些字段显示在 "联系方式" 位置,则代码相同,只是使用的钩子不同:woocommerce_blocks_validate_location_contact_fields。
通过 JSON Schema 实现条件可见性和验证
Schema 在前端实时评估,并在后端进行任何更新时进行评估。 这确保了快速响应的 UI,以及客户端和服务器之间的一致结果。
JSON Schema 结构
数组中的每个 Schema 应该是一个有效的 JSON Schema 对象,该对象定义了何时应应用该属性的条件。 Schema 会针对当前购物车和结账状态进行评估,其中包括所有字段值以及各种选项(支付、配送、客户)。
JSON Schema 对象的基本结构如下:
{
"type": "object",
"properties": {
"fieldId": {
"enum": ["value1", "value2"]
}
},
"required": ["fieldId"]
}
如果您不熟悉 JSON Schema,您可以从 官方网站 了解其基本知识,或者参考一些使用的库,例如 AJV 或 OPIS.。 Checkout 构建了一个基于这两个库的抽象层。
Document 对象
当您撰写规则时,您实际上是在撰写一个 document 对象的局部 结构化数据,本质上是描述您希望字段处于何种理想状态,例如是否需要或隐藏。
重要: document 对象中的所有 属性 都使用 snake_case 命名约定(例如,total_price、shipping_rates、customer_note),而不是 camelCase。
document 对象的一个示例如下:
Document 对象
{
"cart": {
"coupons": [
"my_coupon"
],
"shipping_rates": [
"free_shipping:1"
],
"items": [
27,
27,
68
],
"items_type": [
"simple",
"变体"
],
"items_count": 3,
"items_weight": 0,
"needs_shipping": true,
"prefers_collection": false,
"totals": {
"total_price": 6600,
"total_tax": 600
},
"extensions": {}
},
"checkout": {
"create_account": false,
"customer_note": "",
"additional_fields": {
"namespace/myorder-field": "myvalue"
},
"payment_method": "bacs"
},
"customer": {
"id": 1,
"billing_address": {
"first_name": "名",
"last_name": "姓氏",
"company": "公司",
"address_1": "地址 1",
"address_2": "地址 2",
"city": "城市",
"state": "州",
"postcode": "08000",
"country": "US",
"email": "email@example.com",
"phone": "1234567890",
"namespace/myfield": "myvalue"
},
"shipping_address": {
"first_name": "名",
"last_name": "姓氏",
"company": "公司",
"address_1": "地址 1",
"address_2": "地址 2",
"city": "城市",
"state": "州",
"postcode": "08000",
"country": "US",
"phone": "1234567890",
"namespace/myfield": "myvalue"
},
"additional_fields": {
"namespace/mycontact-field": "myvalue"
},
"address": {
"first_name": "名",
"last_name": "姓氏",
"company": "公司",
"address_1": "地址 1",
"address_2": "地址 2",
"city": "城市",
"state": "州",
"postcode": "08000",
"country": "US",
"phone": "1234567890",
"namespace/myfield": "myvalue"
}
}
}
它完整的结构是这样的:
文档结构
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "购物车和结账文档对象结构",
"description": "购物车、结账和客户信息的文档对象结构,用于条件可见性、字段要求和验证。",
"type": "object",
"properties": {
"cart": {
"type": "object",
"description": "关于购物车的的信息",
"properties": {
"coupons": {
"type": "array",
"description": "应用于购物车的优惠券代码列表",
"items": {
"type": "string"
}
},
"shipping_rates": {
"type": "array",
"description": "当前选择的运输费率列表",
"items": {
"type": "string",
"description": "使用完整运输费率 ID 的运输费率标识符,例如:method_id:instance_id,例如:flat_rate:1"
}
},
"items": {
"type": "array",
"description": "购物车中产品 ID 的列表,ID 将根据产品在购物车中的数量进行重复,如果购物车中有 2 个产品 ID 为 1 的产品,则数组将包含 2 个产品 ID 1 的条目。仅支持整数数量,不支持浮点数(四舍五入到最接近的整数)。",
"items": {
"type": "integer"
}
},
"items_type": {
"type": "array",
"description": "购物车中商品类型,例如:simple、variation、subscription 等。",
"items": {
"type": "string"
}
},
"items_count": {
"type": "integer",
"description": "购物车中商品的总数量",
"minimum": 0
},
"items_weight": {
"type": "number",
"description": "购物车中商品的总重量",
"minimum": 0
},
"needs_shipping": {
"type": "boolean",
"description": "购物车中的商品是否需要运输"
},
"prefers_collection": {
"type": "boolean",
"description": "客户是否更喜欢使用本地自提"
},
"totals": {
"type": "object",
"description": "购物车总价信息",
"properties": {
"total_price": {
"type": "integer",
"description": "购物车总价,以最小货币单位表示(例如:分),在应用所有折扣、运费和税费后"
},
"total_tax": {
"type": "integer",
"description": "总税额,以最小货币单位表示(例如:分),在应用所有折扣、运费和税费后"
}
},
"additionalProperties": false
},
"extensions": {
"type": "object",
"description": "其他购物车扩展数据,这类似于 Store API 的 extensions 参数中传递的数据"
}
},
"additionalProperties": false
},
"checkout": {
"type": "object",
"description": "结账偏好和设置",
"properties": {
"create_account": {
"type": "boolean",
"description": "客户是否选中了创建帐户复选框,如果客户已登录、无法创建帐户或被强制创建帐户,则此值为 false。"
},
"customer_note": {
"type": "string",
"description": "客户的订单备注或特殊说明,如果客户未添加备注,则此字段为空。"
},
"additional_fields": {
"type": "object",
"description": "具有 'order' 位置的附加结账字段。这些字段在订单信息部分中显示。",
"additionalProperties": {
"type": "string"
},
"patternProperties": {
"^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$": {
"type": "string",
"description": "具有命名空间标识符的自定义字段"
}
}
},
"payment_method": {
"type": "string",
"description": "所选的支付方式标识符,无论客户是选择已保存的支付方式还是新的支付方式,此字段都将是支付方式 ID"
}
},
"additionalProperties": false
},
"customer": {
"type": "object",
"description": "客户信息",
"properties": {
"id": {
"type": "integer",
"description": "客户 ID,如果客户未登录,则此值为 0"
},
"billing_address": {
"$ref": "#/definitions/address",
"description": "客户的账单地址"
},
"shipping_address": {
"$ref": "#/definitions/address",
"description": "客户的收货地址"
},
"additional_fields": {
"type": "object",
"description": "具有 'contact' 位置的附加结账字段。这些字段在联系信息部分中显示。",
"additionalProperties": {
"type": "string"
},
"patternProperties": {
"^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$": {
"type": "string",
"description": "具有命名空间标识符的自定义字段"
}
}
},
"address": {
"$ref": "#/definitions/address",
"description": "这是一个动态字段,根据字段评估的上下文,它将是账单地址或收货地址。"
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"address": {
"type": "object",
"description": "客户地址信息",
"properties": {
"first_name": {
"type": "string",
"description": "收件人的名"
},
"last_name": {
"type": "string",
"description": "收件人的姓"
},
"company": {
"type": "string",
"description": "公司名称"
},
"address_1": {
"type": "string",
"description": "主要地址行"
},
"address_2": {
"type": "string",
"description": "辅助地址行"
},
"city": {
"type": "string",
"description": "城市名称"
},
"state": {
"type": "string",
"description": "州或省,如果是预定义的列表,则此字段为州代码,例如:CA、TX、NY 等;如果是自由格式的州,则此字段为字段值,例如:London。"
},
"postcode": {
"type": "string",
"description": "邮政编码"
},
"country": {
"type": "string",
"description": "国家代码(例如:US、UK)"
},
"email": {
"type": "string",
"format": "email",
"description": "Email 地址"
},
"phone": {
"type": "string",
"description": "电话号码"
}
},
"additionalProperties": {
"type": "string",
"description": "具有 'address' 位置的附加字段将在此处以地址对象属性的形式出现"
},
"patternProperties": {
"^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$": {
"type": "string",
"description": "使用命名空间标识符(例如:'namespace/field-name')的具有 'address' 位置的附加字段"
}
}
}
}
}
# 关于 %s 的技术文档
本文档提供了关于 %s 的详细信息。
## 安装
1. 下载 %s 的最新版本。
2. 解压下载的文件。
3. 按照安装说明进行操作。
## 配置
%s 的配置可以通过修改配置文件进行。 配置文件位于 `%s/config/config.ini`。
以下是一些常用的配置选项:
* `server_address`: 服务器地址。
* `server_port`: 服务器端口。
* `database_host`: 数据库主机。
* `database_name`: 数据库名称。
## 使用
要使用 %s,请按照以下步骤操作:
1. 启动 %s 服务器。
2. 使用客户端连接到服务器。
3. 执行所需的命令。
## 示例
以下是一个使用 %s 的示例:
%s --server-address %s --server-port %d
## 故障排除
如果在使用 %s 时遇到问题,请参考以下故障排除步骤:
* 检查配置文件是否正确。
* 检查服务器是否正在运行。
* 检查客户端是否已正确配置。
## 详情
有关 %s 的更多信息,请访问 [https://www.example.com/%s](https://www.example.com/%s)。
## 启用高级功能
要启用高级功能,请修改配置文件并设置 `enable_advanced_features` 为 `true`。
## 日志
%s 将日志信息写入文件 `%s/logs/application.log`。
## 许可证
%s 采用 Apache 2.0 许可证。
## 联系方式
如有任何问题,请通过电子邮件发送至 `support@example.com`。
## 更新日志
* **2023-03-08**: 修复了 %s 的一个 bug。
* **2023-02-15**: 增加了对 %s 的新功能支持。
* **2023-01-01**: 发布了 %s 的第一个版本。
## 常见问题解答
* **问:%s 是什么?**
* 答:%s 是一个用于 %s 的工具。
* **问:如何安装 %s?**
* 答:请参考 "安装" 部分的说明。
* **问:如何配置 %s?**
* 答:请参考 "配置" 部分的说明。
* **问:如何使用 %s?**
* 答:请参考 "使用" 部分的说明。
* **问:%s 的许可证是什么?**
* 答:%s 采用 Apache 2.0 许可证。
## 贡献
欢迎您为 %s 做出贡献。 请访问我们的 GitHub 仓库:[https://github.com/example/%s](https://github.com/example/%s)。
## 感谢
感谢所有为 %s 做出贡献的人。
## 术语表
* **Details**: 详情
* **Enable**: 启用
* **Mar**: 三月
* **In**: 在
* **Down**: 向下
示例
必填且可见的字段
在这个示例中,我们使字段成为必填项,并且仅当选择“本地自提”时才可见。
'required' => [
"type" => "object",
"properties" => [
"cart" => [
"properties" => [
"prefers_collection" => [
"const" => true
]
]
]
]
],
'hidden' => [
"type" => "object",
"properties" => [
"cart" => [
"properties" => [
"prefers_collection" => [
"const" => false
]
]
]
]
]
请注意,对于隐藏的字段,我们反转了该字段的显示状态,这意味着该字段应该仅在 prefers_collection 为 false 时才被隐藏,而 false 几乎适用于所有情况,除非选择了“本地自提”。 在上面的示例中,我们使用了 关键字 const。
验证结构化数据示例
验证与条件可见性和必填性略有不同。 在验证中,您将传入结构化数据的子集(仅适用于您的字段),其作用是验证该字段,并在出现错误时显示错误信息。
在这个示例中,我们确保 VAT 由国家代码和 8-12 个数字组成。
'validation' => [
"type" => "string",
"pattern" => "^[A-Z]{2}[0-9]{8,12}$",
"errorMessage" => "请填写有效的 VAT 代码,该代码应包含 2 个字母作为国家代码,以及 8-12 个数字。"
]
验证还可以针对其他字段,例如,一个备用电子邮件字段,该字段不应与当前的电子邮件匹配:
'validation' => [
"type" => "string",
"format" => "email",
"not" => [
"const" => [ '$data' => "/customer/billing_address/email" ]
],
"errorMessage" => "请填写有效的备用电子邮件。"
]
在上面的示例中,我们使用了 格式关键字 和 $data 来引用当前字段的字段值,方法是通过 JSON 指针。 我们还使用了 errorMessage 属性来提供自定义的错误消息。
$data 关键字和 JSON 指针
$data 关键字是在 JSON 结构化数据中引用另一个字段值的机制。在上面的示例中,我们使用它来引用账单电子邮件,通过 JSON 指针。
在使用 JSON 指针时,需要注意以下几点:
- 正斜杠
/用于在 JSON 对象中导航,因此,对于其他字段,名为my-plugin-namespace/my-field的字段需要引用为my-plugin-namespace~1my-field。 - JSON 指针的导航可以从当前字段向后,也可以从根节点开始。如果您有一个地址字段,并且想要验证电话字段,这意味着您将验证两个值,一个用于配送,一个用于账单,因此您可以以两种方式引用电话字段:
0/customer/address/phone,它使用根导航(通过0/前缀),并使用动态的address组,该组会根据正在验证的配送或账单值而变化。1/phone,它使用相对指针向后移动,在这种情况下,它将访问其兄弟字段,即phone字段。增加数字可以向后移动更远,例如,2/id将访问客户 ID。
不在规范中的关键字和值
我们支持 JSON 结构化数据 Draft-07,它比较简单,不支持所有最新的规范中的关键字和值,但我们认为它涵盖了大多数用例。此外,我们引入了一些非标准的关键字和值,这些值不在规范中,它们的实现可能在 Opis 和 AJV (或任何未来的实现) 之间有所不同。以下是此类关键字和值的列表:
errorMessage: 用于验证的自定义错误信息。在 AJV 中,它是errorMessage,在 Opis 中,它是$error。我们仅支持errorMessage,并在内部将其映射到 Opis。目前,我们不支持在errorMessage中使用模板。$data: 通过 JSON 指针 引用当前字段值。Opis 和 AJV 使用相同的实现。
评估逻辑
- 对于
required: 如果数组中的任何一个结构化数据与当前的结账状态匹配,则该字段将是必填项。 - 对于
hidden: 如果数组中的任何一个结构化数据与当前的结账状态匹配,则该字段将被隐藏。 - 对于
validation: 字段的值将根据提供的部分结构化数据进行评估,如果值不匹配,则会显示错误。
性能考虑
复杂的 JSON 结构化数据条件可能会影响结账性能。请尽可能简化您的结构化数据,并限制条件的数量,仅限于您的用例所需的数量。
向后兼容性
由于技术原因,目前还无法为字段指定元键,因为我们希望它们具有前缀并由系统进行管理。 使用短代码在结账页面上存在的字段的插件可以保持兼容性,并通过钩子来响应字段的读取和保存操作。
假设有两个字段,分别命名为 my-plugin-namespace/address-field (位于地址步骤) 和 my-plugin-namespace/my-other-field (位于订单步骤),您可以:
响应字段保存事件
您可以通过钩入 woocommerce_set_additional_field_value 动作来响应这些字段的保存事件。
add_action(
'woocommerce_set_additional_field_value',
function ( $key, $value, $group, $wc_object ) {
if ( 'my-plugin-namespace/address-field' !== $key ) {
return;
}
if ( 'billing' === $group ) {
$my_plugin_address_key = 'existing_billing_address_field_key';
} else {
$my_plugin_address_key = 'existing_shipping_address_field_key';
}
$wc_object->update_meta_data( $my_plugin_address_key, $value, true );
},
10,
4
);
add_action(
'woocommerce_set_additional_field_value',
function ( $key, $value, $group, $wc_object ) {
if ( 'my-plugin-namespace/my-other-field' !== $key ) {
return;
}
$my_plugin_key = 'existing_order_field_key';
$wc_object->update_meta_data( $my_plugin_key, $value, true );
},
10,
4
);
这样,您可以确保现有的系统能够继续工作,并且您的集成也能继续工作。 但是,理想情况下,您应该迁移现有的数据和系统,以便使用新的元字段。
响应字段读取事件
您可以使用 woocommerce_get_default_value_for_{$key} 过滤器来提供不同的默认值(例如,来自另一个元字段的值):
add_filter(
"woocommerce_get_default_value_for_my-plugin-namespace/address-field",
function ( $value, $group, $wc_object ) {
if ( 'billing' === $group ) {
$my_plugin_key = 'existing_billing_address_field_key';
} else {
$my_plugin_key = 'existing_shipping_address_field_key';
}
return $wc_object->get_meta( $my_plugin_key );
},
10,
3
);
add_filter(
"woocommerce_get_default_value_for_my-plugin-namespace/my-other-field",
function ( $value, $group, $wc_object ) {
$my_plugin_key = 'existing_order_field_key';
return $wc_object->get_meta( $my_plugin_key );
},
10,
3
);
一个完整的示例
在这个完整的示例中,我们将注册“政府身份证”文本字段,并验证它是否符合特定的格式。
这个示例只是前面共享的示例的组合版本。
add_action(
'woocommerce_init',
function() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'namespace/gov-id',
'label' => 'Government ID',
'location' => 'address',
'required' => true,
'attributes' => array(
'autocomplete' => 'government-id',
'pattern' => '[A-Z0-9]{5}', // 由大写字母和数字组成的 5 个字符的字符串。
'title' => 'Your 5-digit Government ID',
),
),
);
woocommerce_register_additional_checkout_field(
array(
'id' => 'namespace/confirm-gov-id',
'label' => 'Confirm government ID',
'location' => 'address',
'required' => true,
'attributes' => array(
'autocomplete' => 'government-id',
'pattern' => '[A-Z0-9]{5}', // 由大写字母和数字组成的 5 个字符的字符串。
'title' => 'Confirm your 5-digit Government ID',
),
),
);
add_action(
'woocommerce_sanitize_additional_field',
function ( $field_value, $field_key ) {
if ( 'namespace/gov-id' === $field_key || 'namespace/confirm-gov-id' === $field_key ) {
$field_value = str_replace( ' ', '', $field_value );
$field_value = strtoupper( $field_value );
}
return $field_value;
},
10,
2
);
add_action(
'woocommerce_validate_additional_field',
function ( WP_Error $errors, $field_key, $field_value ) {
if ( 'namespace/gov-id' === $field_key ) {
$match = preg_match( '/[A-Z0-9]{5}/', $field_value );
if ( 0 === $match || false === $match ) {
$errors->add( 'invalid_gov_id', '请确保您的政府身份证符合正确的格式。' );
}
}
return $errors;
},
10,
3
);
}
);
add_action(
'woocommerce_blocks_validate_location_address_fields',
function ( \WP_Error $errors, $fields, $group ) {
if ( $fields['namespace/gov-id'] !== $fields['namespace/confirm-gov-id'] ) {
$errors->add( 'gov_id_mismatch', '请确保您的政府身份证与确认信息一致。' );
}
},
10,
3
);
可用的插槽
本文档列出了可用的插槽,您可以使用它们来添加自定义内容(填充)。
如果您想添加一个新的 SlotFill 组件,请查看 结账 - 插槽填充 文档。 要了解更多关于插槽和填充的信息,请查看 插槽和填充 文档。
关于命名说明: 以 Experimental 开头的插槽是实验性的,可能会发生更改或被移除。 当它们从实验阶段毕业后,命名会发生变化,并且会删除 Experimental 前缀。 请查看 特性控制 文档,以获取更多信息。
ExperimentalOrderMeta
此插槽在购物车中的“继续结账”按钮上方,以及结账流程中的摘要部分下方进行渲染。
const { __ } = window.wp.i18n;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalOrderMeta } = window.wc.blocksCheckout;
const render = () => {
return (
<ExperimentalOrderMeta>
<div class="wc-block-components-totals-wrapper">
{ __( 'Yearly recurring total ...', 'YOUR-TEXTDOMAIN' ) }
</div>
</ExperimentalOrderMeta>
);
};
registerPlugin( 'slot-and-fill-examples', {
render,
scope: 'woocommerce-checkout',
} );
购物车:

结账:

传递的参数
cart:wc/store/cart数据,但使用camelCase格式,而不是snake_case格式。 对象分解extensions: 由第三方开发者使用ExtendSchema注册的外部数据。 如果您在wc/store/cart上使用了ExtendSchema,您可以在此处找到您的数据,位于您的命名空间下。context: 等于渲染填充的块的名称,可以是woocommerce/cart或woocommerce/checkout。
ExperimentalOrderShippingPackages
此组件在“结账”流程的“配送”步骤以及“购物车”中的“配送选项”中渲染。
const { __ } = window.wp.i18n;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalOrderShippingPackages } = window.wc.blocksCheckout;
const render = () => {
return (
<ExperimentalOrderShippingPackages>
<div>{ __( 'Express Shipping', 'YOUR-TEXTDOMAIN' ) }</div>
</ExperimentalOrderShippingPackages>
);
};
registerPlugin( 'slot-and-fill-examples', {
render,
scope: 'woocommerce-checkout',
} );
购物车:

结账:

传递的参数
collapsible:Boolean|undefined如果配送选项面板应该是可折叠的,如果是,则在“结账”中为false,在“购物车”中为undefined。collapse:Boolean如果面板应该默认折叠,如果是可折叠的,则为true。showItems:Boolean|undefined是否显示每个选项的内容,在“购物车”和“结账”中为undefined,由实际的选项逻辑决定。noResultsMessage: 一个 React 元素,当没有配送选项时,您可以将其渲染。renderOption: 一个渲染函数,它接受一个速率对象并返回一个渲染选项。cart:wc/store/cart数据,但使用camelCase格式,而不是snake_case。 对象分解。extensions: 由第三方开发者使用ExtendSchema注册的外部数据,如果您在wc/store/cart上使用了ExtendSchema,您可以在此处找到您的数据,位于您的命名空间下。components: 一个包含您可以用来渲染您自己的配送费率的组件的对象,它包含ShippingRatesControlPackage。context: 等于渲染填充的块的名称,可以是woocommerce/cart或woocommerce/checkout。
ExperimentalOrderLocalPickupPackages
此组件在结账页面的“结账”块中的“取货选项”区域内渲染。 它不会在购物车块中渲染。
const { __ } = window.wp.i18n;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalOrderLocalPickupPackages } = window.wc.blocksCheckout;
const render = () => {
return (
<ExperimentalOrderLocalPickupPackages>
<div>
{ __(
'通过使用我们便捷的本地自提选项,您可以来我们的商店取您的订单。 当您的订单准备好取货时,我们会通过电子邮件通知您。',
'YOUR-TEXTDOMAIN'
) }
</div>
</ExperimentalOrderLocalPickupPackages>
);
};
registerPlugin( 'slot-and-fill-examples', {
render,
scope: 'woocommerce-checkout',
} );
结账:

已传递的参数
renderPickupLocation: 一个渲染函数,用于渲染本地自提选项的地址详情。cart:wc/store/cart的数据,但使用camelCase格式,而不是snake_case。 对象分解。extensions: 由第三方开发者使用ExtendSchema注册的外部数据。 如果您在wc/store/cart上使用了ExtendSchema,您可以在此处找到您的数据,位于您的命名空间下。components: 一个包含组件的对象,您可以使用这些组件来渲染您自己的取货费用。 它包含ShippingRatesControlPackage和RadioControl。
ExperimentalDiscountsMeta
此组件在 CouponCode 输入框下方渲染。
const { __ } = window.wp.i18n;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalDiscountsMeta } = window.wc.blocksCheckout;
const render = () => {
return (
<ExperimentalDiscountsMeta>
<div class="wc-block-components-totals-wrapper">
{ __( '您有 98683 积分可用于消费...', 'YOUR-TEXTDOMAIN' ) }
</div>
</ExperimentalDiscountsMeta>
);
};
registerPlugin( 'slot-and-fill-examples', {
render,
scope: 'woocommerce-checkout',
} );
购物车:

结账:

传递的参数
cart:wc/store/cart数据,但使用了camelCase格式,而不是snake_case格式。 对象分解extensions: 由第三方开发者使用ExtendSchema注册的外部数据。 如果您在wc/store/cart上使用了ExtendSchema,您可以在此处找到您的数据,它位于您的命名空间下。context: 等于渲染填充的阻止的名称:woocommerce/cart或woocommerce/checkout。
结账工具
提供用于结账功能的实用函数和 React 钩子,这些功能来自 @woocommerce/blocks-checkout。
useValidateCheckout
一个钩子,用于验证结账表单,并在发现任何错误时自动滚动到第一个验证错误。
此钩子主要由 PlaceOrderButton 组件内部使用,以向自定义的下单按钮组件提供 validate 属性。 但是,如果需要,也可以直接使用它。
使用方法
// 别名导入
import { useValidateCheckout } from '@woocommerce/blocks-checkout';
// 全局导入
// const { useValidateCheckout } = wc.blocksCheckout;
const MyComponent = () => {
const validateCheckout = useValidateCheckout();
const handleClick = async () => {
const { hasError } = await validateCheckout();
if ( hasError ) {
// 验证失败 - 错误会自动显示,
// 并且页面会滚动到第一个错误元素
return;
}
// 验证通过 - 继续执行您的逻辑
};
return <button onClick={ handleClick }>Validate</button>;
};
返回值
该钩子返回一个函数,当调用该函数时:
- 触发
CHECKOUT_VALIDATION事件以运行所有已注册的验证回调。 - 检查验证存储以查找任何字段级别的验证错误。
- 如果发现错误:
- 显示所有验证错误。
- 滚动到并聚焦第一个错误元素。
- 返回一个 promise,其结果为
{ hasError: boolean }。
| 属性 | 类型 | 描述 |
|---|---|---|
hasError |
boolean |
如果验证失败则为 true,如果验证通过则为 false。 |
DOM 事件
某些块需要响应某些事件,以便显示最新的数据或以特定方式运行。 例如,购物车块必须监听“加入购物车”事件,以便更新购物车的内容;或者迷你购物车块,每当一个产品被添加到购物车时,它就会打开。
WooCommerce 核心事件在 WooCommerce 块中的应用
WooCommerce 核心使用 jQuery 事件来触发和监听某些事件,例如当产品被添加到或从购物车中移除时。 在 WooCommerce 块中,我们已经不再使用 jQuery,但我们仍然需要监听这些事件。 为了实现这一点,我们有一个名为 translatejQueryEventToNative() 的实用程序,它监听这些 jQuery 事件,并且每当一个事件被触发时,它会触发一个相关的 DOM 原生事件(带有 wc-blocks_ 前缀)。
WooCommerce 块事件
wc-blocks_adding_to_cart
这个事件相当于 WooCommerce 核心触发的 jQuery 事件 adding_to_cart。 它表示将产品添加到购物车的过程已发送到服务器,但尚未有任何指示表明该产品是否已成功添加。
在 WC 块中的示例用法: 迷你购物车块监听此事件以附加其依赖项。
wc-blocks_added_to_cart
这个事件相当于 WooCommerce 核心触发的 jQuery 事件 added_to_cart。 它表示将产品添加到购物车的过程已成功完成。
在 WC 块中的示例用法: 购物车和迷你购物车块(通过 useStoreCart() 钩子)监听此事件,以了解它们是否需要更新其内容。
detail 参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
preserveCartData |
boolean | false |
是否保留商店中的购物车数据。 默认情况下,其值为 false,因此任何 wc-blocks_added_to_cart 事件都会使购物车数据失效,并且监听该事件的块会再次获取购物车数据。 但是,如果触发事件的代码已经更新了商店(例如:所有产品块),则可以设置 preserveCartData: true 以避免其他块再次获取数据。 |
wc-blocks_removed_from_cart
此事件等同于 WooCommerce 核心触发的 jQuery 事件 removed_from_cart。 它表示一个产品已从购物车中移除。
在 WC Blocks 中的用法示例: 购物车和迷你购物车块(通过 useStoreCart 钩子)会监听此事件,以了解它们是否需要更新其内容。
结账模块如何处理订单
本文将深入探讨结账流程的内部机制。更具体地说,当用户点击“提交订单”按钮后会发生什么。
结构
以下区域与处理用户的结账过程相关。
支付注册表 (文件)
支付注册表存储每个支付方法的所有配置信息。 我们可以使用 registerPaymentMethod 和 registerExpressPaymentMethod 函数在此处注册新的支付方法,这些函数也供其他插件使用。
数据存储
数据存储用于跟踪可能在用户会话期间发生变化的数据,例如,当前使用的支付方法、结账是否存在错误等。 我们根据关注的领域对这些数据存储进行分割,因此我们有两个与结账相关的数据存储:wc/store/checkout (文件) 和 wc/store/payment (文件)。 数据存储位于 assets/js/data 文件夹中。
上下文 (Contexts)
上下文用于将数据提供给结账模块。 每个上下文都通过钩子提供与特定领域相关的数据和函数。 例如,如果我们要使用 PaymentEventsContext 上下文中的 onPaymentSetup 句柄,可以这样操作:
const { onPaymentSetup } = usePaymentEventsContext();
上下文的另一个作用是为我们的结账模块运行副作用。 通常,CheckoutEvents 和 PaymentEvents 会监听结账和支付数据存储的变化,并根据某些逻辑,基于这些变化分发操作到这些存储中。
例如,在 CheckoutEvents 上下文中,当结账状态为 before_processing 时,我们会分发 emitValidateEvent 操作。 还有很多类似的逻辑,它们会响应来自这两个存储的状态和数据的变化。
结账上下文包括:
| 上下文 | 描述 |
|---|---|
| CheckoutEvents | 提供与结账相关的事件句柄 |
| PaymentEvents | 提供与支付相关的事件句柄 |
| CustomerData | 提供与当前客户相关的数据 |
| ShippingData | 提供与配送相关的错误数据和操作 |
结账处理器 (checkout-processor.js)
结账处理器组件会订阅结账或支付数据存储的变化,将部分数据打包起来,并在满足条件时调用 Store API 的 /checkout 接口。
结账提供者
结账提供者 将上述所有上下文封装在 CheckoutProcessor 组件中。
结账用户流程
以下是完整的结账流程:
1. 点击“提交订单”按钮
结账流程从用户点击按钮开始。
2. 结账状态设置为 before_processing 文件
当用户点击“提交订单”按钮后,我们将结账状态更改为 "before_processing"。 在这里,我们处理结账信息的验证。
3. 触发 checkout_validation_before_processing 事件 文件
在这里,WooCommerce Blocks 插件和其他插件可以注册事件监听器来处理验证。 此事件的监听器将运行,如果存在错误,我们将结账状态设置为 idle 并向用户显示错误。
如果没有错误,我们将进入下面的第 4 步。
4. 结账状态设置为 processing 文件
processing 状态由下面的第 5 步用于更改付款状态。
5. 付款状态设置为 processing 文件
在完成所有结账处理并且没有错误后,付款处理开始。
6. 触发 payment_processing 事件 文件
触发 payment_processing 事件。 其他插件可以注册此事件的监听器并运行自己的代码。
例如,Stripe 插件在这里检查地址和付款详情,并使用 Stripe API 在 Stripe 中创建客户和付款参考。
重要提示:实际的付款操作不是在这里进行的。它像一个预付款钩子,用于在尝试实际付款之前运行任何付款插件的代码。
7. 执行 payment_processing 事件监听器,并根据情况设置付款和结账状态 (file)
如果注册的事件监听器返回错误,我们将向用户显示该错误。
如果事件监听器被认为是成功的,我们将同步结账的地址与付款地址,将 paymentMethodData 存储在付款存储中,并设置付款状态属性 { isProcessing: true }。
8. POST 请求发送到 /wc/store/v1/checkout (file)
如果不存在付款错误,则会调用 /checkout StoreApi 端点。该端点会获取最终的客户地址和选择的付款方式,以及任何其他付款数据,然后尝试付款并返回结果。
重要:付款尝试是通过 StoreApi 进行的,而不是通过从客户端发送的 payment_processing 事件。
9. 触发 processCheckoutResponse 操作,该操作作用于结账存储 (file)
一旦对 StoreApi /checkout 端点的请求返回响应,我们将该响应传递给 checkout 数据存储中的 processCheckoutResponse 操作。
它将执行以下操作:
- 它设置重定向 URL,用于在订单完成后重定向到该 URL。
- 它将付款结果存储在
checkout数据存储中。 - 它将结账状态更改为
after_processing(步骤 10)。
10. 将结账状态设置为 after_processing (file)
after_processing 状态表示我们已完成主要的结账处理步骤。在此步骤中,我们执行清理操作,并显示在上一步骤中触发的任何错误。
11. 发出 checkout_after_processing_with_success 事件 (file)
如果没有错误,则会触发 checkout_after_processing_with_success 事件。这是其他插件可以在结账过程成功后运行代码的地方。
在 checkout_after_processing_with_success 事件上注册的任何事件监听器都将被执行。如果事件监听器没有返回错误,则会调用 checkout 数据存储中的 setComplete 操作,以将状态设置为 complete(步骤 13)。事件监听器也可能在此处返回错误,该错误将显示给用户。
12. 发出 checkout_after_processing_with_error 事件 (文件)
如果从第 5 步出现错误,则会发出 checkout_after_processing_with_error 事件。 其他插件可以注册事件监听器,以便在此处向用户显示错误。 事件监听器会被处理,并将任何错误显示给用户。
13. 将结账状态设置为 complete (文件)
如果没有错误,则在结账数据存储中的 status 属性会更改为 complete。 这表示结账流程已完成。
14. 重定向 (文件)
一旦结账状态设置为 complete,如果存在 redirectUrl 在结账数据存储中,则会将用户重定向到该网址。
其他值得注意的事项
检查付款方式
一个付款方式会与一个 配置对象 关联。它必须包含一个名为 canMakePayment 的函数。如果该付款方式可以用于支付当前的购物车,则该函数应返回 true。当前的购物车(商品、地址、配送方式等)会传递给此函数,并且每个付款方式负责报告它是否可用。
checkPaymentMethodsCanPay() 函数 会遍历所有已注册的付款方式,检查它们是否可用,如果可用,则将它们添加到支付数据存储器上的 availablePaymentMethods 属性。
必须在几个地方调用 checkPaymentMethodsCanPay() 函数,以便在将付款方式显示给用户作为可选项之前进行验证。
移除结账字段
如果您正在尝试扩展新的结账 Block,您可能会注意到之前的 checkout_fields 不起作用。这是有意为之,因为我们希望提供更多经过精心设计的扩展方式。 尽管如此,我们最常收到的一项请求是,如何为某些订单类型禁用结账字段。 我们不鼓励这样做,但由于这项请求非常普遍,我们在这里分享相关 Details。
为什么我们不鼓励移除字段
原因很简单:结账功能非常复杂,许多插件需要不同的数据。例如,Payment methods 需要您的地址信息来进行欺诈检测或验证您的卡,税费(包括核心税费)需要您的完整地址才能正确计算税费。 我们仍在考虑如何在结账功能中找到一个通用的解决方案。 在我们找到该解决方案之前,以下 document 将帮助您移除结账字段。
禁用单个国家/地区的字段
结账字段仍然遵循国家/地区设置,这意味着您可以通过 PHP 修改某个国家/地区的字段,并且这会正常工作。 以下的账单表单有 10 个字段,其中 7 个是必填项:
假设在阿尔及利亚,我们确信邮政编码和城市是冗余的,因此我们可以移除它们:
add_filter('woocommerce_get_country_locale', function( $locale ) {
$locale['DZ']['postcode']['required'] = false;
$locale['DZ']['postcode']['hidden'] = true;
$locale['DZ']['city']['required'] = false;
$locale['DZ']['city']['hidden'] = true;
return $locale;
});
通过上面的代码,这两个字段都已从阿尔及利亚移除,但未从其他国家/地区移除,这是一个安全且良好的更新。
请记住,这会同时移除 Shipping 和 Billing 的字段。 我们强烈认为 Billing 的 Shape 应该与 Shipping 的 Shape 匹配。
移除所有字段,仅保留国家和姓名
我们可以采取以下步骤,移除除了国家之外的所有其他字段。移除国家字段会导致您的订单失败,因为我们需要国家信息来确定要移除哪些字段:
add_filter('woocommerce_get_country_locale', function( $locale ) {
$locale['DZ']['address_1'] = [
'required' => false,
'hidden' => true,
];
$locale['DZ']['postcode'] = [
'required' => false,
'hidden' => true,
];
$locale['DZ']['city'] = [
'required' => false,
'hidden' => true,
];
$locale['DZ']['company'] = [
'required' => false,
'hidden' => true,
];
$locale['DZ']['state'] = [
'required' => false,
'hidden' => true,
];
$locale['DZ']['phone'] = [
'required' => false,
'hidden' => true,
];
return $locale;
});
结果如下:
您会注意到,地址行 2 不可见。这是因为如果地址行 1 被隐藏,地址行 2 也会被自动隐藏。
移除公司和电话
如果可以访问网站,一种简单的方法是从编辑器中切换关闭这些字段:
结果如下:
通过代码移除公司和电话
与其他的字段不同,电话、公司和地址 2 的信息是通过一个选项持久化到数据库中的:
woocommerce_checkout_phone_fieldwoocommerce_checkout_company_fieldwoocommerce_checkout_address_2_field
这些选项的值可以是:required(必填)、optional(可选)或 hidden(隐藏)。它们管理字段的默认状态。您可以编辑这些选项,但同时也允许商家根据自己的需要进行设置。您还可以根据地区/国家进行编辑。
要编辑默认值:
add_filter(
'default_option_woocommerce_checkout_phone_field',
function ( $default_value ) {
return "required";
},
10,
1
);
如果您想根据地区(覆盖该国家/地区的商户设置)来更改值,可以使用上面的示例。
到目前为止,所有更改都仅应用于阿尔及利亚。其他国家的客户将看到适合其所在国家的正确字段:
将更改应用于您销售的所有国家/地区
与上述类似,我们不建议这样做,除非您只面向非常有限的国家/地区,并且已经针对每个国家/地区进行了测试。 某些 支付网关 仅在 生产模式 下启用欺诈检测,而不在 测试模式 下启用,并且在 测试模式 下通过的 字段 可能在 生产模式 下失败。 但无论如何,以下是代码:
add_filter('woocommerce_get_country_locale', function( $locale ) {
foreach ( $locale as $key => $value ) {
$locale[ $key ]['address_1'] = [
'required' => false,
'hidden' => true,
];
$locale[ $key ]['postcode'] = [
'required' => false,
'hidden' => true,
];
$locale[ $key ]['city'] = [
'required' => false,
'hidden' => true,
];
$locale[ $key ]['state'] = [
'required' => false,
'hidden' => true,
];
}
return $locale;
});
上述代码会循环遍历您销售的所有国家/地区,并禁用这些 字段。
限制更改仅适用于虚拟购物车
我们可以选择仅从 虚拟购物车 (仅需要账单信息,不需要 配送 信息) 中移除 字段,这可以通过一些额外的检查来实现:
add_filter('woocommerce_get_country_locale', function( $locale ) {
$cart = wc()->cart;
// 仅当正在处理购物车时才移除 `字段`。
if ( ! $cart ) {
return $locale;
}
// 仅当处理的是虚拟购物车时才移除 `字段`。
if ( $cart->needs_shipping() ) {
return $locale;
}
// 执行以下逻辑...
编辑地址卡文本
在以后的访问中,结账 页面会显示已保存 地址 的地址卡,目前该功能在账单方面可能无法始终正常工作,但一旦正常工作,它会显示如下:
我们可以使用 PHP 编辑该文本,因为该值来自 get_address_formats 函数,该函数通过 woocommerce_localisation_address_formats 过滤器。
我们可以使用以下代码:
add_filter( 'woocommerce_localisation_address_formats', function( $formats ) {
foreach ( $formats as $key => $format ) {
$formats[ $key ] = "{first_name} {last_name}\n{country}";
// 您也可以使用 `{name}` 代替 `名` 和 `姓氏`。
}
return $formats;
} );
请注意,您需要将 字符串 放在双引号中才能使其生效;否则,换行符将无法被识别。
结账流程和事件
本文档概述了 WooCommerce 结账模块中的结账流程,并提供了一些通用的架构概览。
结账模块的架构源于以下原则:
- 在结账流程中,数据拥有单一的权威来源。
- 为扩展集成提供一致的界面(例如,付款方式)。此界面保护结账过程的完整性,并将扩展逻辑与结账逻辑隔离。结账模块负责处理所有与服务器的通信,用于处理订单。扩展可以通过提供的界面与结账模块交互并进行通信。
- 结账流程的状态由结账状态跟踪。
- 扩展可以通过订阅发出的事件来与结账流程进行交互。
以下是流程的高层概览:

通用概念
通过状态跟踪流程
在结账生命周期的任何阶段,组件都应能够准确检测结账流程的状态。这包括以下内容:
- 是否正在加载内容?正在加载什么内容?
- 是否存在错误?是什么错误?
- 结账是否正在计算总额?
在某些情况下,使用简单的布尔值可能就足够了,但在其他情况下,它可能会导致复杂的条件判断和容易出错的代码(尤其是在处理对各种流程状态做出反应的逻辑行为时)。
为了显示流程状态,该模块使用状态,这些状态在各种上下文中进行跟踪。尽可能地,这些状态是内部设置的,以响应各种操作,因此子组件不需要实现(组件只需要_消费_状态,而不需要设置状态)。
以下是在 Checkout 中存在的状态。
结账数据存储状态
通过选择器,结账数据存储会暴露各种状态。所有选择器的详细信息如下,并在 结账 API 文档 中进行说明。
您可以在组件中使用它们,例如:
const { useSelect } = window.wp.data;
const { checkoutStore } = window.wc.wcBlocksData;
const MyComponent = ( props ) => {
const isComplete = useSelect( ( select ) =>
select( checkoutStore ).isComplete()
);
// 对 isComplete 进行操作
};
以下是与状态相关的可用布尔标志:
isIdle: 当结账状态为 IDLE 时,此标志为真。在块加载后,任何对结账状态的更改都会使结账处于此状态。当在处理过程中出现错误后,如果可以重试购买,结账也会处于此状态。
isBeforeProcessing: 当结账状态为 BEFORE_PROCESSING 时,此标志为真。当用户提交结账以进行处理时,结账将处于此状态。
isProcessing: 当结账状态为 PROCESSING 时,此标志为真。当所有在 BEFORE_PROCESSING 状态下触发的事件观察器完成且没有错误时,结账将处于此状态。在此状态下,块会向服务器发送请求,访问结账端点以处理订单。注意: 在此状态下,还会发生一些付款状态的更改(请参阅 PaymentProvider 暴露的状态部分)。
isAfterProcessing: 当结账状态为 AFTER_PROCESSING 时,此标志为真。当块从服务器端处理请求接收到响应后,结账将处于此状态。
isComplete: 当结账状态为 COMPLETE 时,此标志为真。当所有在 AFTER_PROCESSING 状态下触发的事件观察器成功完成后,结账将处于此状态。当结账处于此状态时,购物者的浏览器将被重定向到 redirectUrl 的值(通常是 order-received 路由)。
特殊状态
以下布尔值通过结账提供程序暴露。 它们彼此独立,并且与结账状态不同,但可以组合使用,以响应结账过程中的各种状态。
isCalculating
isCalculating 在以下两种情况下为真:当订单的总价正在重新计算时,或者当一个插件使用 disableCheckoutFor 动作(将在下一节中介绍)有意地禁用结账流程时。
有很多因素可能触发总价的重新计算,例如添加或删除优惠券、更新运费、选择运费等。与其检查每个单独的状态,您可以可靠地检查这个布尔值是否为真(计算中)或假(未计算中)。
isCalculating 影响:
- 禁用结账区块中的“提交订单”按钮。
- 禁用购物车区块中的“继续结账”按钮。
- 在计算过程中,显示快速支付方式的加载状态。
使用 disableCheckoutFor 控制 isCalculating
您可以使用 disableCheckoutFor 函数来编程地控制 isCalculating:
const { dispatch } = window.wp.data;
const { checkoutStore } = window.wc.wcBlocksData;
// 示例:在执行异步操作时禁用结账
dispatch( checkoutStore ).disableCheckoutFor( async () => {
// 在此处执行您的异步操作,例如使用 API 验证数据
await myAsyncOperation();
// 无需返回任何值 - 我们只关心 Promise 是否已解析
} );
该函数控制内部状态,确保客户端在提供的 Promise 解析之前无法尝试完成流程,无论成功与否。
hasError
hasError 在结账流程的任何部分出现错误状态时为真。这可能包括验证错误、请求错误、优惠券应用错误、支付处理错误等。
ShippingProvider 暴露的 Status
shipping 上下文提供者暴露了与 shipping 相关的全部信息。这包括一组错误 status,用于指示 shipping 上下文所处的错误状态。该错误状态受服务器对地址更改、费率检索和选择的 requests 影响。
当前,错误 status 可能为 NONE、INVALID_ADDRESS 或 UNKNOWN(请注意,此值可能会在未来更改)。
status 通过 useShippingDataContext Hook 提供的 currentErrorStatus 对象暴露。该对象具有以下 property:
isPristine和isValid:这两个布尔值都与相同的错误status相关联。当status为NONE时,这两个布尔值的取值为true。它基本上意味着没有shipping错误。hasInvalidAddress:当提供的shipping地址无效时,此值为true。hasError:当shipping的错误status为UNKNOWN或hasInvalidAddress时,此值为true。
付款方式数据存储状态
付款的状态存储在付款数据存储中。您可以使用以下选择器查询状态:
const { select } = window.wp.data;
const { paymentStore } = window.wc.wcBlocksData;
const MyComponent = ( props ) => {
const isPaymentIdle = select( paymentStore ).isPaymentIdle();
const isExpressPaymentStarted =
select( paymentStore ).isExpressPaymentStarted();
const isPaymentProcessing = select( paymentStore ).isPaymentProcessing();
const isPaymentReady = select( paymentStore ).isPaymentReady();
const hasPaymentError = select( paymentStore ).hasPaymentError();
// 对布尔值进行操作
};
这里的状态将有助于了解_客户端_处理的当前****状态,并且会在结账处理周期的不同阶段通过商店操作进行更新。_客户端_是指在注册的、活动的付款方式中,当结账表单通过这些注册的客户端组件提交时,处理任何付款的状态。 尽管如此,付款方式在处理订单时可能仍然存在额外的服务器端处理,但这不会反映在这些状态中(更多信息请参见付款方式集成文档)。
可能设置的_内部_状态包括:
IDLE: 这是在初始化结账且存在未执行任何操作的付款方式时的状态。 每当结账状态更改为IDLE时,也会设置此状态。EXPRESS_STARTED: 仅限快速 付款方式 - 当用户点击其按钮触发快速付款方式时,将使用此状态。 此流程发生在处理之前,通常在一个模态窗口中。PROCESSING: 当结账状态为PROCESSING,结账hasError为false,结账未进行计算,并且当前****付款状态不是FINISHED时,将设置此状态。 当设置此状态时,将触发付款处理事件发射器。READY: 在所有已连接到付款处理事件的观察者成功完成后,将设置此状态。CheckoutProcessor组件使用此状态以及结账PROCESSING状态来表示准备好将订单数据发送到服务器进行处理,并进行付款。ERROR: 当连接到付款处理事件的观察者返回错误响应后,将设置此状态。 这将导致结账hasError标志设置为true。
发送事件
另一个影响可扩展性的关键点是,提供既具有指导性又灵活的界面,以便扩展程序可以响应和处理流程中的特定事件。 为了保证系统的稳定性,核心结账流程应_控制_所有与服务器的通信,这些通信与结账/订单处理相关,并将扩展程序特定的需求留给扩展程序自行处理。 这样可以使扩展程序能够根据需要,以可预测的方式与结账数据和流程进行交互,而不会影响其他与之挂钩的扩展程序。
实现这种类型可扩展性的最可靠方法是使用事件系统。 因此,各种上下文提供器:
- 提供订阅 API,允许扩展程序订阅对特定事件做出反应的_观察者_。
- 在结账流程的特定点触发事件,这些事件会将数据传递给已注册的观察者,并在某些情况下,根据观察者的回复做出相应的反应。
当在任何事件发射器中注册观察者时,有一个_非常重要_的规则,那就是它们_不能_更新上下文状态。 仅对特定组件的局部状态进行更新是可以的,但不能修改任何上下文或全局状态。 原因是观察者回调函数是按顺序在特定点执行的,因此,注册到同一事件的后续观察者将无法响应早期执行的观察者中全局/上下文状态的任何更改。
const unsubscribe = emitter(myCallback);
您可以将您正在注册的任何发射器替换为 emitter 函数。 例如,如果您正在注册 onCheckoutValidation 事件发射器,则代码如下:
const unsubscribe = onCheckoutValidation(myCallback);
您还可以指定希望您的观察者以何种优先级执行。 较低的优先级在较高的优先级之前运行,因此您可以控制您的观察者在已注册到发射器的观察者堆栈中何时运行。 您可以通过在第二个参数中指定一个数值来指示优先级:
const unsubscribe = onCheckoutValidation(myCallback, 10);
在示例中,myCallback 是您的订阅函数。 订阅函数可以从事件发射器接收数据(如在“发射器详情”中描述的),并且可能需要以特定的格式返回一个回复(也在“特定发射器详情”中描述)。 订阅函数可以是 Promise,并且当事件发射器循环遍历已注册的观察者时,它将等待任何已注册的 Promise 完成。
最后,调用发射器函数的返回值是一个取消订阅函数,该函数可用于取消注册您的观察者。 这在 React 组件上下文中特别有用,您需要在组件卸载时确保取消注册观察者。 例如,可以在 useEffect 钩子中使用:
Event Emitter Utilities
这里有一些与事件相关的实用方法。这些方法位于 assets/js/base/context/event-emit/utils.ts 文件中,可以按以下方式导入:
import {
noticeContexts,
responseTypes,
shouldRetry,
} from '@woocommerce/base-context';
import {
isSuccessResponse,
isErrorResponse,
isFailResponse,
} from '@woocommerce/types';
以下是辅助函数的描述:
isSuccessResponse,isErrorResponse和isFailResponse: 这些是辅助函数,它们接收一个值,并通过布尔值报告该对象是否为预期的响应类型。对于接收来自注册观察者的响应的事件发射器,返回对象的type属性指示响应的类型,事件发射器会根据该类型做出反应。例如,如果观察者返回{ type: 'success' },则发射器可以将该值传递给isSuccessResponse,该函数将返回true。您可以在 支付处理事件发射器 的实现中看到一个示例。noticeContexts: 这是一个对象,包含引用可以在结账过程中定位通知的区域的属性。该对象具有以下属性:PAYMENTS: 这是对支付方式步骤中通知区域的引用。EXPRESS_PAYMENTS: 这是对快速支付方式步骤中通知区域的引用。
responseTypes: 这是一个对象,包含引用某些事件发射器可以返回的各种响应类型的属性。 这使得自动完成类型更容易,并避免了由于人为错误导致的拼写错误。 类型为SUCCESS、FAIL和ERROR。 这些类型的对应值与 结账端点响应 中的 付款状态类型。shouldRetry: 这是一个函数,包含在结账流程中是否允许用户在之前的付款失败后重试付款的逻辑。 它接收response对象,并且默认情况下检查retry属性是否为true、undefined或false。 有关更多详细信息,请参阅onCheckoutSuccess文档。
技术文档
注意: noticeContexts 和 responseTypes 通过传递给其组件的 emitResponse 属性,暴露给 付款方式。
const MyPaymentMethodComponent = ( { emitResponse } ) => {
const { noticeContexts, responseTypes } = emitResponse;
// 其他 `付款方式` 的逻辑...
};
以下 活动 允许 扩展 注册观察者:
onCheckoutValidation
注册到此事件发射器的观察者将不会接收任何参数。 此外,所有观察者将在结账处理来自发射器的回复之前执行。 注册到此发射器的观察者可以返回 true,表示它们没有需要返回给结账的信息;返回 false,表示希望结账返回到 IDLE 状态;或者返回一个包含以下属性的对象:
errorMessage: 这将作为错误通知添加到结账上下文。validationErrors: 这将设置为结账字段中的内联验证错误。 如果您的观察者希望触发验证错误,可以使用以下结构:- 这是一个对象,其中键是验证错误的属性名称(对应于结账字段,例如
country或coupon),值是描述验证问题的错误消息。
- 这是一个对象,其中键是验证错误的属性名称(对应于结账字段,例如
当结账状态为 BEFORE_PROCESSING 时(这发生在验证时,在用户触发结账表单提交或使用 Express 付款方式之后),会触发此事件。
如果所有观察者都为该事件返回 true,则结账状态将更改为 PROCESSING。
可以通过使用 useCheckoutContext 钩子从结账上下文或作为属性在已注册的组件中,获取此事件发射器的订阅者:
用于内部开发:
import { useCheckoutContext } from '@woocommerce/base-contexts';
import { useEffect } from '@wordpress/element';
const Component = () => {
const { onCheckoutValidation } = useCheckoutContext();
useEffect( () => {
const unsubscribe = onCheckoutValidation( () => true );
return unsubscribe;
}, [ onCheckoutValidation ] );
return null;
};
用于已注册的付款方式组件:
const { useEffect } = window.wp.element;
const PaymentMethodComponent = ( { eventRegistration } ) => {
const { onCheckoutValidation } = eventRegistration;
useEffect( () => {
const unsubscribe = onCheckoutValidation( () => true );
return unsubscribe;
}, [ onCheckoutValidation ] );
};
用于其他情况:
const { onCheckoutValidation } = wc.blocksCheckoutEvents;
useEffect( () => {
const unsubscribe = onCheckoutValidation( () => true );
return unsubscribe;
}, [ onCheckoutValidation ] );
onPaymentProcessing
onPaymentProcessing此功能已过时,并已替换为 onPaymentSetup 事件发射器。
onPaymentSetup
当支付方式上下文的 Status 为 PROCESSING 时,此事件触发器会被激活。Status 的设置条件是:结账的 Status 为 PROCESSING,结账没有 Error,结账没有正在计算,并且当前的支付 Status 不是 FINISHED。
此事件触发器会依次执行所有已注册的观察者(不传递任何参数)。当某个观察者返回非真值时,事件触发器会停止执行后续的已注册观察者。
当支付方式返回非真值时,如果返回的是有效的响应类型,事件触发器会根据响应更新各种内部 Status。以下是事件触发器可能处理的响应类型:
成功
当用户的输入数据正确且支付验证成功时,应返回成功的响应。一个响应被认为是成功的,至少应是具有以下结构的 Object:
const successResponse = { type: 'success' };
当返回成功的响应时,支付方式上下文的 Status 会更改为 SUCCESS。此外,包含以下任何额外的 Property 会触发额外的 Actions:
paymentMethodData: 此对象的Contents将作为payment_data的值,当结账向服务器发送请求以处理订单时,该值会被包含在请求中。如果支付方式需要进行额外的服务器端处理,则此功能非常有用。billingAddress: 允许支付方式更新结账中的任何账单信息(通常由 Express 支付方式使用),以便将其包含在发送给服务器的结账处理请求中。此数据应符合 此处 描述的结构。shippingAddress: 允许支付方式更新订单的任何配送信息(通常由 Express 支付方式使用),以便将其包含在发送给服务器的结账处理请求中。此数据应符合 此处 描述的结构。
如果响应对象中没有 billingAddress 或 shippingAddress Property,则相关数据的 Status 将保持不变。
失败
当支付处理出现错误时,应返回失败的回复。一个回复被认为是失败回复,当它是一个具有以下结构的 JSON 对象时:
const failResponse = { type: 'failure' };
当观察者返回一个失败回复时,支付方法上下文的状态将被更改为 FAIL。此外,包含以下任何属性会导致额外的操作:
message: 这里提供的字符串将被设置为结账中的错误提示。messageContext: 如果提供,这将指定错误提示的目标区域(这与前面提到的noticeContexts相关)。否则,提示将添加到noticeContexts.PAYMENTS区域。paymentMethodData: (与成功回复相同)。billingAddress: (与成功回复相同)。
错误
当用户在结账表单中输入存在错误时,应返回错误响应。 响应被认为是错误响应,当它是一个具有以下结构的 对象时:
const errorResponse = { type: 'error' };
当观察者返回错误响应时,支付方法上下文状态将更改为 ERROR。 此外,包含以下任何属性将导致额外的操作:
message: 在此处提供的字符串将被设置为错误提示。messageContext: 如果提供,这将针对指定的区域显示错误提示(这与前面提到的noticeContexts相关)。 否则,提示将添加到noticeContexts.PAYMENTS区域。validationErrors: 这将设置为结账字段中的内联验证错误。 如果观察者希望触发验证错误,可以使用以下结构来定义错误:- 这是一个对象,其中键是验证错误的属性名称(对应于结账字段,例如
country或coupon),值是描述验证问题的错误消息。
- 这是一个对象,其中键是验证错误的属性名称(对应于结账字段,例如
如果响应对象不符合上述任何条件,则默认情况下将支付状态设置为 SUCCESS。
当支付状态设置为 SUCCESS 并且结账状态为 PROCESSING 时,CheckoutProcessor 组件将触发向服务器发送请求以处理订单。
可以通过使用 usePaymentEventsContext 钩子获取结账上下文,或者作为已注册组件的属性,将此事件发射器订阅者提供给支付方法扩展:
用于内部开发:
import { usePaymentEventsContext } from '@woocommerce/base-contexts';
import { useEffect } from '@wordpress/element';
const Component = () => {
const { onPaymentSetup } = usePaymentEventsContext();
useEffect( () => {
const unsubscribe = onPaymentSetup( () => true );
return unsubscribe;
}, [ onPaymentSetup ] );
return null;
};
用于已注册的支付方法组件:
const { useEffect } = window.wp.element;
const PaymentMethodComponent = ( { eventRegistration } ) => {
const { onPaymentSetup } = eventRegistration;
useEffect( () => {
const unsubscribe = onPaymentSetup( () => true );
return unsubscribe;
}, [ onPaymentSetup ] );
};
onCheckoutSuccess
当结账状态为 AFTER_PROCESSING 且结账的 hasError 状态为 false 时,会触发此事件发射器。AFTER_PROCESSING 状态由 CheckoutProcessor 组件在接收到服务器对结账处理请求的响应后设置。
注册到此事件发射器的观察者将接收以下对象作为参数:
const onCheckoutProcessingData = {
redirectUrl,
orderId,
customerId,
orderNotes,
paymentResult,
};
属性如下:
redirectUrl: 这是一个字符串,表示结账将重定向到的 URL,由服务器上的处理过程返回。orderId: 是当前正在处理的订单的 ID。customerId: 是进行购买的客户的 ID(该 ID 与订单相关联)。orderNotes: 这是客户在订单上留下的任何自定义备注。paymentResult: 这是来自/checkoutStoreApi 响应的payment_result的值 (https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/34e17c3622637dbe8b02fac47b5c9b9ebf9e3596/src/RestApi/StoreApi/Schemas/CheckoutSchema.php#L103-L138)。 此对象中暴露的数据(通过对象的属性):paymentStatus: 支付在服务器端处理后的状态。可能的值为success、failure、pending或error。paymentDetails: 这将是一个任意对象,包含付款方式处理服务器端在结账处理响应中返回给客户端的任何数据。付款方式可以通过钩子在服务器端进行处理,并设置此数据。
此事件发射器将依次调用所有已注册的观察者,直到任何一个观察者的响应不等于 true。 此时,任何未调用的观察者将被跳过,并且触发中止的观察者的响应将被处理。
此发射器将处理 success 类型的响应 ({ type: success }),并将结账状态设置为 COMPLETE。 此外,如果响应包含 redirectUrl,则结账将重定向到指定的地址。
此发射器还将处理 failure 类型的响应或 error 类型的响应,如果检测到无效的类型,则将其视为 error 类型的响应。
在所有情况下,如果响应中包含以下属性,则会执行额外的操作:
结账状态处理
以下描述了如何处理结账状态。
message: 此字符串将被添加为错误通知。
messageContext: 如果存在,则该通知将被配置为显示在指定的通知区域(否则,它将只是结账块的通用通知)。
retry: 如果此值为 true 或未定义,则结账状态将被设置为 IDLE。 这基本上意味着该错误是可以恢复的(例如,尝试不同的支付方式),因此结账将被重置为 IDLE 以供购物者再次尝试。 如果此值为 false,则结账状态将被设置为 COMPLETE,并且结账将重定向到当前设置为 redirectUrl 的 URL。
redirectUrl: 如果此参数存在,则当状态为 COMPLETE 时,结账将重定向到此 URL。
如果所有观察者都返回 true,则结账状态将仅设置为 COMPLETE。
此事件发射器订阅者可以通过使用 useCheckoutContext 钩子获取结账上下文,或者作为已注册组件的属性提供给支付方式扩展。
用于内部开发:
import { useCheckoutContext } from '@woocommerce/base-contexts';
import { useEffect } from '@wordpress/element';
const Component = () => {
const { onCheckoutSuccess } = useCheckoutContext();
useEffect( () => {
const unsubscribe = onCheckoutSuccess( () => true );
return unsubscribe;
}, [ onCheckoutSuccess ] );
return null;
};
用于已注册的支付方式组件:
const { useEffect } = window.wp.element;
const PaymentMethodComponent = ( { eventRegistration } ) => {
const { onCheckoutSuccess } = eventRegistration;
useEffect( () => {
const unsubscribe = onCheckoutSuccess( () => true );
return unsubscribe;
}, [ onCheckoutSuccess ] );
};
用于其他情况:
const { onCheckoutSuccess } = wc.blocksCheckoutEvents;
useEffect( () => {
const unsubscribe = onCheckoutSuccess( () => true );
return unsubscribe;
}, [ onCheckoutSuccess ] );
onCheckoutFail
当结账状态为 AFTER_PROCESSING 且结账的 hasError 状态为 true 时,会触发此事件发射器。AFTER_PROCESSING 状态由 CheckoutProcessor 组件在接收到服务器对结账处理请求的响应后设置。
注册到此发射器的观察者将接收到与注册到 onCheckoutSuccess 相同的的数据包。
来自第一个观察者的响应,如果返回的值不 === true,则处理方式与 onCheckoutSuccess 类似,但仅处理类型为 error 或 failure 的情况。
如果所有观察者都返回 true,则结账状态将直接设置为 IDLE,并在结账上下文中显示默认错误提示。
可以通过结账上下文使用 useCheckoutContext 钩子,或作为属性传递给已注册的支付方式组件来获取此事件发射器的订阅者:
用于内部开发:
import { useCheckoutContext } from '@woocommerce/base-contexts';
import { useEffect } from '@wordpress/element';
const Component = () => {
const { onCheckoutFail } = useCheckoutContext();
useEffect( () => {
const unsubscribe = onCheckoutFail( () => true );
return unsubscribe;
}, [ onCheckoutFail ] );
return null;
};
用于已注册的支付方式组件:
const { useEffect } = window.wp.element;
const PaymentMethodComponent = ( { eventRegistration } ) => {
const { onCheckoutFail } = eventRegistration;
useEffect( () => {
const unsubscribe = onCheckoutFail( () => true );
return unsubscribe;
}, [ onCheckoutFail ] );
};
用于其他情况:
const { onCheckoutFail } = wc.blocksCheckoutEvents;
useEffect( () => {
const unsubscribe = onCheckoutFail( () => true );
return unsubscribe;
}, [ onCheckoutFail ] );
onShippingRateSuccess
当运费信息未加载,且运费数据上下文的错误状态为 NONE,并且存在可用的运费信息时,会触发此事件发射器。
此事件发射器不关心任何已注册的观察者的响应,而是简单地执行所有已注册的观察者,并将从服务器检索到的当前运费信息传递给它们。
onShippingRateFail
当运费信息未加载,且运费数据上下文的错误状态为 UNKNOWN 或 INVALID_ADDRESS 时,会触发此事件发射器。
此事件发射器不关心任何已注册的观察者的响应,而是简单地执行所有已注册的观察者,并将当前的错误状态传递给它们。
onShippingRateSelectSuccess
当运费选择未持久化到服务器,并且存在已选择的运费信息,且当前上下文中的错误状态为 NONE 时,会触发此事件发射器。
此事件发射器不关心任何已注册的观察者的响应,而是简单地执行所有已注册的观察者,并将当前的已选择运费信息传递给它们。
onShippingRateSelectFail
当配送费率选择未能保存到服务器,并且配送数据上下文的错误状态为 UNKNOWN 或 INVALID_ADDRESS 时,会触发此事件发射器。
此事件发射器不关心任何已注册的观察者的响应,它将简单地执行所有已注册的观察者,并将当前的错误状态传递给它们。
在结账块中过滤付款方式
问题
您是一名扩展开发者,您的扩展有条件地隐藏结账步骤中的支付网关。您需要使用前端可扩展性点来隐藏结账块中的支付网关。
解决方案
WooCommerce Blocks 提供了名为 registerPaymentMethodExtensionCallbacks 的函数,允许扩展注册回调函数,用于特定付款方式,以确定是否可以进行支付。
导入
别名导入
import { registerPaymentMethodExtensionCallbacks } from '@woocommerce/blocks-registry';
wc global
const { registerPaymentMethodExtensionCallbacks } = window.wc.wcBlocksRegistry;
签名
| 参数 | 描述 | 类型 |
|---|---|---|
namespace |
用于标识您的扩展的唯一字符串。选择一个能够避免与其他扩展发生命名冲突的名称。 | string |
callbacks |
包含为不同付款方式注册的回调函数的对象 | Record< string, CanMakePaymentExtensionCallback > |
请参阅以下关于 为付款方式注册的回调函数 的更多信息。
扩展命名空间冲突
当尝试在已使用 registerPaymentMethodExtensionCallbacks 的扩展命名空间下注册回调函数时,注册将被中止,并且您将收到通知,表明您没有使用唯一的命名空间。 这将在 JavaScript 控制台中显示。
使用示例
registerPaymentMethodExtensionCallbacks( 'my-hypothetical-extension', {
cod: ( arg ) => {
return arg.shippingAddress.city === 'Berlin';
},
cheque: ( arg ) => {
return false;
},
} );
为付款方式注册的回调函数
扩展程序只能为每种付款方式注册一个回调函数:
payment_method_name: (arg) => {...}
payment_method_name 是在向 WooCommerce Blocks 注册付款方式时使用的 name 属性 的值。
注册的回调函数用于确定相应的付款方式是否应作为购物者的可用选项。 该函数将传递一个包含有关当前订单的数据的对象。
type CanMakePaymentExtensionCallback = (
cartData: CanMakePaymentArgument
) => boolean;
每个回调函数都可以访问以下信息:
interface CanMakePaymentArgument {
cart: Cart;
cartTotals: CartTotals;
cartNeedsShipping: boolean;
billingAddress: CartResponseBillingAddress;
shippingAddress: CartResponseShippingAddress;
selectedShippingMethods: Record< string, unknown >;
paymentRequirements: Array< string >;
}
如果需要回调函数接收的参数中没有的数据,您可以考虑 在 Store API 中公开您的数据。
使用要求过滤付款方式
问题
您的扩展程序以一种方式向您的商店添加了功能,即只有特定的支付网关才能处理包含某些产品的订单。
例如,如果购物者将 Bookable 产品添加到购物车,例如酒店住宿,并且您(作为商家)希望在付款之前确认所有预订,您仍然需要捕获客户的结账详细信息,但此时不需要他们的付款方式。
解决方案
为了允许购物者在不输入付款详细信息的情况下结账,但仍然要求他们填写其他结账详细信息,您可以创建一个新的付款方式,该付款方式将处理包含 Bookable 项目的购物车。
通过使用付款方式的 supports 配置,可以防止其他付款方式(例如信用卡、PayPal 等)被用于结账,并且仅允许您的扩展程序添加的付款方式出现在结账块中。
有关如何向 WooCommerce Blocks 注册付款方式的更多信息,请参阅 付款方式集成 文档。
基本用法
请参考上方链接的文档,注册您的付款方式,并为其指定一个唯一的 supports 特性,例如 booking_availability。这将用于隔离该付款方式,防止其他付款方式显示。
首先,您需要创建一个函数,该函数将检查购物车的内容,以确定购物车所需的特定付款要求。以下是一个针对我们的 Bookable 产品执行此操作的示例。
然后,您需要在 ExtendSchema 类中使用 register_payment_requirements,以告知结账模块执行一个回调函数来检查这些要求。
整合所有内容
此代码示例假设存在一个名为 Pseudo_Booking_Class 的类,该类具有 cart_contains_bookable_product 方法。 此方法的实现在此处不相关。
/**
* 检查购物车的内容,并添加所需的付款方式。
*
*
* @return array 购物车中项目所需的特性列表。
*/
function inject_payment_feature_requirements_for_cart_api() {
// 如果购物车包含可预订的产品,则返回一个包含我们要求的 `booking_availability` 的数组。
if ( Pseudo_Booking_Class::cart_contains_bookable_product() ) {
return array( 'booking_availability' );
}
// 购物车中没有可预订的产品,无需添加任何内容。
return array();
}
总结上述内容:如果购物车中包含可预订的产品,则此函数将返回一个包含 booking_availability 的数组,否则,它将返回一个空数组。
下一步是告诉 ExtendSchema 类,在检查要显示的付款方式时,执行此回调函数。
为此,您可以使用以下代码:
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_payment_requirements(
array(
'data_callback' => 'inject_payment_feature_requirements_for_cart_api',
)
);
});
重要的是要注意此代码块中的注释:您必须不要实例化 ExtendSchema 的自定义版本。
如果您已正确添加您的付款方式,并为其指定了正确的 supports 值,那么当您在购物车中包含 Bookable 项目时访问结账页面时,任何不支持 booking_availability 要求的付款方式都应该不显示,而您的付款方式,即_支持_此要求的付款方式_将_显示。
付款方式集成
客户端集成
客户端集成包括一个 API,用于注册 常规 和 快速 付款方式。
在两种情况下,客户端集成都是通过 blocks-registry API 提供的注册方法来完成的。您可以通过 WooCommerce 环境中的 wc 全局对象 (wc.wcBlocksRegistry) 访问它。
注意:在您的构建过程中,您可以执行类似于 blocks 仓库中执行的操作,该操作将此 API 作为外部 API 别名为
@woocommerce/blocks-registry(https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/e089ae17043fa525e8397d605f0f470959f2ae95/bin/webpack-helpers.js#L16-L35)。
快速付款方式
快速付款方式是指由购物者发起的、包含一键支付流程的付款方式,例如 Stripe、ApplePay 或 GooglePay。

注册
要注册一种快速付款方式,您可以使用来自 blocks 注册表的 registerExpressPaymentMethod 函数。
const { registerExpressPaymentMethod } = window.wc.wcBlocksRegistry;
如果您使用 @woocommerce/blocks-registry 的别名导入,您可以这样导入该函数:
import { registerExpressPaymentMethod } from '@woocommerce/blocks-registry';
注册函数期望一个包含特定于付款方式的选项的 JavaScript 对象:
registerExpressPaymentMethod( options );
您传递给配置实例的选项应该是一个具有以下结构的 对象(请参阅 ExpressPaymentMethodConfiguration 类型定义):
const options = {
name: 'my_payment_method',
title: 'My Mayment Method',
description: '一两句话描述您的付款方式',
gatewayId: 'gateway-id',
label: <ReactNode />,
content: <ReactNode />,
edit: <ReactNode />,
canMakePayment: () => true,
paymentMethodId: 'my_payment_method',
supports: {
features: [],
style: [],
},
};
ExpressPaymentMethodConfiguration
| 选项 | 类型 | 描述 | 必需 |
|---|---|---|---|
name |
字符串 | 网关客户端的唯一标识符。 | 是 |
title |
字符串 | 您的支付方式的人性化名称。在编辑器中向商家显示。 | 否 |
description |
字符串 | 描述您的支付网关的简短文字(一到两句话)。在编辑器中向商家显示。 | 否 |
gatewayId |
字符串 | 注册服务器端的支付网关的 ID。用于将商家引导到编辑器中的正确设置页面。如果未提供此 ID,商家将被重定向到 WooCommerce 的常规支付设置页面。 | 否 |
content |
ReactNode | 当在前端渲染块时,在快速支付方式区域输出的 React 节点。从结账支付方式界面接收 props。 | 是 |
edit |
ReactNode | 当在编辑器中渲染块时,在快速支付方式区域输出的 React 节点。从支付方式界面接收 props,用于预览数据。 | 是 |
canMakePayment |
函数 | 回调函数,用于确定该支付方式是否应为用户可用。 | 是 |
paymentMethodId |
字符串 | 伴随发送到服务器的结账处理请求的标识符。用于标识用于处理支付的支付方式网关类。 | 否 |
supports:features |
数组 | 网关支持的支付功能的数组。用于检查该支付方式是否可用于购物车中的商品。如果未提供任何值,则默认为 ['products']。 |
否 |
supports:style |
数组 | 这是一个快速支付方式支持的样式变化数组。这些样式应用于所有活动的快速支付方式按钮,并且可以在编辑器中的快速支付方式块中进行控制。支持的值之一是 ['height', 'borderRadius']。 |
否 |
canMakePayment 选项
canMakePayment 是一个回调函数,用于确定付款方式是否应该作为购物者的可用选项。该函数将传递一个包含有关当前订单的数据的对象。
canMakePayment( {
cart: Cart,
cartTotals: CartTotals,
cartNeedsShipping: boolean,
shippingAddress: CartShippingAddress,
billingAddress: CartBillingAddress,
selectedShippingMethods: Record<string,unknown>,
paymentRequirements: string[],
} )
canMakePayment 返回一个布尔值。如果您的支付网关需要执行异步初始化以确定可用性,您可以返回一个 Promise(解析为布尔值)。这允许根据购物车隐藏某些付款方式,例如,如果购物车包含实物/可运送的商品(例如:货到付款);或者,用于控制付款方式的可用性,具体取决于其他条件。
canMakePayment 仅在商店的前端运行。在编辑器上下文中,而不是使用 canMakePayment,编辑器会假定付款方式可用(true),以便向商家显示定义的 edit 组件。
请注意,此函数可能在结账的生命周期中被多次调用,因此,在提供的此属性的回调函数中,任何耗时的逻辑都应该进行缓存。
快速支付方式的按钮属性
此 API 提供了一种同步快速支付方式按钮外观的方法,以提供一致的购物体验。快速支付方式应优先使用 buttonAttributes 中提供的值,并在按钮渲染在购物车或结账阻止之外的地方时,使用其自身的配置设置作为备份。
例如,在您的按钮组件中,您可能会执行以下操作:
// 获取您的扩展特定的设置,如果未提供则设置默认值
let {
borderRadius = '4',
height = '48',
} = getButtonSettingsFromConfig();
// 在购物车和结账块上下文中,我们接收 `buttonAttributes` 作为属性,这些属性会覆盖扩展特定的设置
if ( typeof buttonAttributes !== 'undefined' ) {
height = buttonAttributes.height;
borderRadius = buttonAttributes.borderRadius;
}
...
return <button style={height: `${height}px`, borderRadius: `${borderRadius}px`} />
付款方式
付款方式是显示在结账块中的付款方式选项。例如,包括 支票、PayPal 标准和 Stripe 信用卡。

注册
要注册一种付款方式,您可以使用 registerPaymentMethod 函数,该函数位于 blocks 注册表中。
const { registerPaymentMethod } = window.wc.wcBlocksRegistry;
如果您使用别名导入 @woocommerce/blocks-registry,则可以这样导入该函数:
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
注册函数期望一个包含特定于付款方式的选项的 JavaScript 对象:
registerPaymentMethod( options );
您传递给配置实例的选项应该是一个具有以下结构的 对象(请参阅 PaymentMethodRegistrationOptions 类型定义)。 您传递给配置实例的选项与用于快速付款方式的选项相同,但增加了以下内容:
| 属性 | 类型 | 描述 |
|---|---|---|
savedTokenComponent |
ReactNode | 一个 React 节点,包含处理已保存付款方式的逻辑。 当客户选择此付款方式的已保存令牌时,会进行渲染。 |
label |
ReactNode | 一个用于输出付款方式选项标签的 React 节点。 它可以是文本或图像。 |
ariaLabel |
string | 当选择付款方式时,屏幕阅读器读取的标签。 |
placeOrderButtonLabel |
string | 可选标签,用于更改当选择此付款方式时,默认的“提交订单”按钮的文本。 与 placeOrderButton 互斥。 |
placeOrderButton |
React Component | 可选的 React 组件,用于替换当选择此付款方式时,默认的“提交订单”按钮。 与 placeOrderButtonLabel 互斥。 该组件接收 PaymentMethodInterface 属性。 |
supports |
object | 包含关于支持功能的的信息: |
supports.showSavedCards |
boolean | 确定是否向客户显示此付款方式的已保存卡片。 |
supports.showSaveOption |
boolean | 控制是否显示用于将付款方式保存以供将来使用的复选框。 |
使用自定义“提交订单”按钮
您的自定义按钮组件会接收与付款方式 content 组件相同的属性,并通过 PaymentMethodInterface 传递,此外还包含一些与按钮相关的附加属性:
waitingForProcessing- 是否正在处理结账过程。waitingForRedirect- 是否正在等待成功后进行重定向。disabled- 是否应禁用按钮。isEditor- 按钮是否正在块编辑器中渲染。isPreview- 按钮是否正在预览模式下渲染。
以下是一个简单的示例:
const CustomButton = ( props ) => {
const { validate, onSubmit, disabled, isEditor, isPreview, eventRegistration: { onPaymentSetup }, emitResponse } = props;
const [
isShowingInternalPaymentSheet,
setIsShowingInternalPaymentSheet,
] = React.useState( false );
const paymentResultRef = React.useRef( false );
const handleClick = async () => {
// 1. 验证结账表单
const validationResult = await validate();
if ( validationResult.hasError ) {
return; // WooCommerce 会自动显示验证错误
}
// 2. 显示您的付款界面(例如,Google Pay 界面、Apple Pay 界面)
// setIsShowingInternalPaymentSheet( true );
// const paymentResult = await showPaymentSheet( billing.cartTotal.value );
// paymentResultRef.current = paymentResult.success;
// if ( ! paymentResult.success ) {
// setIsShowingInternalPaymentSheet( false );
// return;
// }
// 3. 在收集到所有付款信息后,将结账提交到服务器。
onSubmit();
};
React.useEffect(
() =>
onPaymentSetup( () => {
return ({
type: paymentResultRef.current ? emitResponse.responseTypes.SUCCESS : emitResponse.responseTypes.ERROR,
meta: {
paymentMethodData: {
payment_method: 'your-payment-method',
},
},
});
} ),
[ onPaymentSetup, emitResponse.responseTypes.SUCCESS, emitResponse.responseTypes.ERROR ]
);
// 在编辑器/预览模式下,显示一个占位符或预览版本
if ( isEditor || isPreview ) {
return (
<button type="button" disabled>
使用自定义方式支付 (预览)
</button>
);
}
return (
<button
type="button"
onClick={ handleClick }
disabled={ disabled || isShowingInternalPaymentSheet }
>
{ disabled || isShowingInternalPaymentSheet
? '处理中...'
: '使用自定义方式支付' }
</button>
);
};
**注册自定义付款方式**
本指南介绍了如何注册自定义付款方式。
**内容:**
* **产品:** 自定义付款方式
* **选择:** 注册自定义付款方式
* **按钮:** 注册按钮
* **方法:** `registerPaymentMethod`
* **标签:** 付款方式标签
* **订单:** 订单
* **编辑:** 编辑按钮
* **保存:** 保存按钮
* **显示:** 显示区域
* **列表:** 付款方式列表
* **端口:** 无
* **使用:** 使用指南
* **在:** 在页面中
* **否:** 否
* **付款方式:** 付款方式
* **描述:** 描述信息
* **下单:** 下单按钮
* **已选中:** 已选择状态
```javascript
registerPaymentMethod( {
name: 'my-custom-payment',
label: <div>我的自定义付款方式</div>,
content: <div>付款方式描述</div>,
edit: <div>付款方式描述</div>,
placeOrderButton: CustomButton,
canMakePayment: () => true,
supports: {
features: [ 'products' ],
},
} );
注意: 自定义按钮仅在从列表中选择付款方式时才会显示。 当选择已保存的付款凭证时,将使用默认的“下单”按钮。
传递给付款方式节点的属性
付款方式集成的一个重要部分是,当提供的节点被克隆并在区块挂载时渲染时,会通过属性向付款方式暴露的界面。虽然所有属性都列在下面,但您可以在 此文件中描述的类型定义 中找到有关这些属性引用的对象、它们的类型等的更多详情。
属性说明
| Property | Type | Description |
|---|---|---|
activePaymentMethod |
String | 当前结账流程中活动的付款方式的别名。 |
billing |
包含 billingAddress, cartTotal, currency, cartTotalItems, displayPricesIncludingTax, appliedCoupons, customerId 属性的对象 |
包含所有与账单相关的信息。 |
cartData |
包含 cartItems, cartFees, extensions 属性的对象 |
暴露的购物车数据,包括商品、费用以及任何已注册的扩展数据。 请注意,这些数据应被视为不可变的(不应修改),否则会导致应用程序出现错误。 |
checkoutStatus |
包含 isCalculating, isComplete, isIdle, isProcessing 属性的对象 |
以各种布尔状态暴露的当前结账状态。 |
components |
包含 ValidationInputError, PaymentMethodLabel, PaymentMethodIcons, LoadingMask 属性的对象 |
暴露 React 组件,这些组件可以由您的付款方式用于各种常见的付款方式界面元素。 |
emitResponse |
包含 noticeContexts 和 responseTypes 属性的对象 |
包含一些常量,在事件发射器中使用时可能很有用。 请阅读 事件发射 部分以获取更多详细信息。 |
eventRegistration |
包含 onCheckoutValidation, onCheckoutSuccess, onCheckoutFail, onPaymentSetup, onShippingRateSuccess, onShippingRateFail, onShippingRateSelectSuccess, onShippingRateSelectFail 属性的对象 |
包含所有结账事件发射器注册函数。 这些是付款方式可以注册观察者以与结账流程的各个阶段进行交互的函数(请参阅 此文档 以获取更多信息)。 |
onClick |
Function | 提供给表达付款方式,当付款方式按钮被点击时触发(这将向结账发出信号,表明付款方式已接管付款处理)。 |
onClose |
Function | 提供给表达付款方式,当快速付款方式模态框关闭并控制权返回到结账时触发。 |
onSubmit |
Function | 提交结账并开始处理。 |
validate |
Function | 异步函数,用于在不提交的情况下验证结账表单。 返回一个解析为 { hasError: boolean } 的 Promise。 当您需要在显示付款方式之前进行验证时,此功能很有用。 |
buttonAttributes |
包含 height, borderRadius 属性的对象 |
由商家设置的样式,所有快速付款方式按钮都应遵守这些样式。 |
paymentStatus |
Object | 各种付款状态辅助函数。 请注意,您的付款方式不必在客户端设置此状态。 结账将通过您的付款方式从注册到 结账事件发射器 的回复来处理此操作。 |
paymentStatus.isPristine |
Boolean | 当当前付款状态为 PRISTINE 时,此值为 true。 |
paymentStatus.isStarted |
Boolean | 当当前付款状态为 EXPRESS_STARTED 时,此值为 true。 |
paymentStatus.isProcessing |
Boolean | 当当前付款状态为 PROCESSING 时,此值为 true。 |
paymentStatus.isFinished |
Boolean | 当当前付款状态为 ERROR, FAILED 或 SUCCESS 中的任何一个时,此值为 true。 |
paymentStatus.hasError |
Boolean | 当当前付款状态为 ERROR 时,此值为 true。 |
paymentStatus.hasFailed |
Boolean | 当当前付款状态为 FAILED 时,此值为 true。 |
paymentStatus.isSuccessful |
Boolean | 当当前付款状态为 SUCCESS 时,此值为 true。 |
setExpressPaymentError |
Function | 接收一个字符串,允许快速付款方式在需要时为快速付款区域设置错误通知。 这可能是必要的,因为某些快速付款方式的处理可能发生在结账事件之外。 |
shippingData |
包含 shippingRates, shippingRatesLoading, selectedRates, setSelectedRates, isSelectingRate, shippingAddress, setShippingAddress, needsShipping 属性的对象 |
包含所有与运输相关的数据(不包括运输状态)。 |
shippingStatus |
包含 shippingErrorStatus, shippingErrorTypes 属性的对象 |
各种运输状态辅助函数。 |
shouldSavePayment |
Boolean | 指示购物者是否选择保存其付款方式详细信息(适用于支持保存付款方式的付款方式)。 如果已选择,则为 true;否则为 false。 默认为 false。 |
任何已注册的 savedTokenComponent 节点也会接收一个 token 属性,该属性包含所选择的已保存令牌的 ID,以备您的支付方法需要将其用于某些内部逻辑。但是,请记住,这只是代表该令牌在数据库中的 ID(以及购物者选中的单选框的值),而不是实际的客户支付令牌(因为通常在服务器上进行处理以确保安全)。
服务器端集成
对于服务器端集成,您需要创建一个类,该类需要继承 Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType 类。
这个类是您付款方式的服务器端表示。它用于在正确的时间,将您的付款方式资源注册到商店 API 和结账模块。它与您需要单独实现的 支付网关 API 不同,后者用于处理支付。
示例支付方式集成类
<?php
namespace MyPlugin\MyPaymentMethod;
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
final class MyPaymentMethodType extends AbstractPaymentMethodType {
/**
* 此属性是一个字符串,用于引用您的支付方式。 重要的是要使用与客户端 JavaScript 支付方式注册中相同的名称。
*
* @var string
*/
protected $name = 'my_payment_method';
/**
* 初始化支付方式。
*
* 此函数将在服务器端初始化过程中被调用,并且是放置任何设置等内容的理想位置。 基本上,您需要做任何事情来初始化您的网关。
*
* 请注意,此函数将在每个请求中被调用,因此请不要在此处放置任何耗时操作。
*/
public function initialize() {
$this->settings = get_option( 'woocommerce_my_payment_method_settings', [] );
}
/**
* 此函数应返回支付方式是否处于活动状态。
*
* 如果为 false,则不会加载脚本。
*
* @return boolean
*/
public function is_active() {
return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN );
}
/**
* 返回一个要注册的脚本/句柄的数组,用于此支付方式。
*
* 在此函数中,您应该注册您的支付方式脚本(使用 `wp_register_script`),然后返回您注册的脚本句柄。 这将用于将您的支付方式作为结账脚本的依赖项,从而确保正确加载它。
*
* 请注意,您仍然应该确保您的脚本具有的其他任何资源依赖项都已在此处正确注册。 如果您使用 Webpack 构建资源,您可能希望使用 WooCommerce Webpack 依赖项提取插件
* (https://www.npmjs.com/package/@woocommerce/dependency-extraction-webpack-plugin) 来使此过程更容易。
*
* @return array
*/
public function get_payment_method_script_handles() {
wp_register_script(
'my-payment-method',
'path/to/your/script/my-payment-method.js',
[],
'1.0.0',
true
);
return [ 'my-payment-method' ];
}
/**
* 返回一个要为管理后台排队的脚本句柄的数组。
*
* 如果您的支付方式有一个脚本,您_只想_在结账块的编辑器上下文加载,则包含此脚本。
* 将 `get_payment_method_script_handles` 中的任何脚本也包含在此处,如果它们也需要在管理后台加载。
*/
public function get_payment_method_script_handles_for_admin() {
return $this->get_payment_method_script_handles();
}
/**
* 返回一个键值对数组,这些数据可供付款方式脚本客户端使用。
*
* 这些数据可以通过 `wc.wcSettings.getSetting` 在客户端访问。例如,如果您将 `stripe` 赋值为该类的 `name` 属性,则可以在客户端通过以下方式访问任何数据:
* `wc.wcSettings.getSetting( 'stripe_data' )`。这将返回一个对象,其形状与您从此函数返回的关联数组匹配。
*
* @return array
*/
public function get_payment_method_data() {
return [
'title' => $this->get_setting( 'title' ),
'description' => $this->get_setting( 'description' ),
'supports' => $this->get_supported_features(),
];
}
}
文档
这是一个示例文档,其中包含一些常用的术语。
设置
- Settings → 设置
- Payment methods → 付款方式
- Available → 可用
- Property → 属性
- Method → 方法
- Access → 访问
- Title → 标题
- Value → 价值
- Shape → 形状
- Class → 类
- Data → 数据
- Port → 端口
- Via → 通过
- Key → 关键字
- For → 为
- Tan → 褐色
- Cc → 抄送
- In → 在
- Description → 描述
- Assigned → 已分配
示例
这是一个示例段落,演示如何使用上述术语。
例如,您可以在 设置 中配置 付款方式。每个 付款方式 都有自己的 属性 和 方法。您可以通过 访问 相应的 端口 来获取 数据。
列表
以下是一个列表,其中包含一些常用的命令:
command1command2command3
代码示例
以下是一个代码示例,演示如何使用 get_payment_method_data 函数:
/**
* Returns an array of key=>value pairs of data made available to the payment methods script client side.
*
* This data will be available client side via `wc.wcSettings.getSetting`. So for instance if you assigned `stripe` as the
* value of the `name` property for this class, client side you can access any data via:
* `wc.wcSettings.getSetting( 'stripe_data' )`. That would return an object matching the shape of the associative array
* you returned from this function.
*
* @return array
*/
public function get_payment_method_data() {
return [
'title' => $this->get_setting( 'title' ),
'description' => $this->get_setting( 'description' ),
'supports' => $this->get_supported_features(),
];
}
}
占位符和 HTML 标签
以下是一个包含占位符和 HTML 标签的示例:
This is a string with a placeholder: %s.
<p>This is a paragraph.</p>
URL 链接
以下是一个 URL 链接:
函数名、变量名、命令名
函数名、变量名和命令名应保持英文原文。例如:MyFunction, myVariable, myCommand.
### 注册付款方式集成
在创建了一个继承自 `Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType` 的类之后,您需要将其注册到服务器端的付款方式处理模块。
您可以通过使用 `PaymentMethodRegistry` 类的 `register` 方法来实现。
```php
use MyPlugin\MyPaymentMethod\MyPaymentMethodType;
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
add_action(
'woocommerce_blocks_payment_method_type_registration',
function( PaymentMethodRegistry $payment_method_registry ) {
$payment_method_registry->register( new MyPaymentMethodType() );
}
);
处理付款(旧版本支持)
付款仍然通过 支付网关 API 进行处理。 这与上面用于付款方式集成的 API 是不同的。
结账模块将客户端脚本提供的 payment_data 转换为 $_POST,并调用支付网关的 process_payment 方法。
如果您已经集成了 WooCommerce 付款方式扩展,并且使用了短代码结账流程,那么旧版本的处理方式将负责在服务器端处理您的付款。
通过商店 API 处理支付
在某些更高级的场景下,之前提到的旧版支付处理方式可能无法满足您现有的支付方式集成需求。对于这些情况,还提供了一个动作钩子,您可以使用它来处理服务器端的订单处理,它提供了更多的上下文信息,并且专用于商店 API。
这个钩子是集成支付处理的首选位置:
do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$result ] );
注意:在您之前创建的支付方式类型类的
initialize方法中注册您的回调函数是一个不错的选择。
在该钩子上注册的回调函数将接收到:
- 一个
PaymentContext对象,其中包含所选的payment_method(这与在注册支付方式时定义的paymentMethodId值相同),正在创建的order,以及由支付方式客户端提供的任何额外的payment_data。 - 一个
PaymentResult对象,您可以使用它来通过商店 API 将状态、重定向 URL 以及任何其他支付详情返回给客户端。
如果您在提供的 PaymentResult 对象上设置了状态,则您的支付方式将不再使用旧版支付处理方式。如果发生错误,您的回调函数可以抛出异常,该异常将由商店 API 处理。
以下是一个示例回调函数:
add_action(
'woocommerce_rest_checkout_process_payment_with_context',
function( $context, $result ) {
if ( $context->payment_method === 'my_payment_method' ) {
// 订单处理逻辑将在此处执行!
// $context->order 包含订单对象,如果需要
// ...
// 如果上述逻辑成功,我们可以将状态设置为成功。
$result->set_status( 'success' );
$result->set_payment_details(
array_merge(
$result->payment_details,
[
'custom-data' => '12345',
]
)
);
$result->set_redirect_url( 'some/url/to/redirect/to' );
}
},
10,
2
);
从客户端传递值到服务器端支付处理
在这个例子中,我们将从 BACS 支付方法传递一些数据到服务器。BACS 的注册过程大致如下:
// 获取在注册支付方法时提供的设置
const settings = window.wc.wcSettings.getSetting( 'bacs_data' );
// 这是一个组件,当选择 BACS 支付方法时,它将在结账块中渲染
const Content = () => {
return decodeEntities( settings?.description || '' );
};
// 这是一个支付方法的标签
const Label = ( props ) => {
const { PaymentMethodLabel } = props.components;
return <PaymentMethodLabel text={ decodeEntities( settings?.title || 'BACS' ) } />;
};
// 注册支付方法
const bankTransferPaymentMethod = {
name: 'BACS',
label: <Label />,
content: <Content />,
edit: <Content />,
canMakePayment: () => true,
supports: {
features: settings?.supports ?? [],
},
};
支付方法节点会传递所有数据,这些数据来自 usePaymentMethodInterface 钩子。因此,我们可以在我们的 <Content /> 组件中使用它,如下所示:
const Content = ( props ) => {
const { eventRegistration, emitResponse } = props;
const { onPaymentProcessing } = eventRegistration;
useEffect( () => {
const unsubscribe = onPaymentProcessing( async () => {
// 可以在这里执行任何需要的处理,然后发出响应。
// 例如,我们可以验证一个自定义字段,或者执行一个 AJAX 请求,然后发出一个响应,指示其是否有效。
const myGatewayCustomData = '12345';
const customDataIsValid = !! myGatewayCustomData.length;
if ( customDataIsValid ) {
return {
type: emitResponse.responseTypes.SUCCESS,
meta: {
paymentMethodData: {
myGatewayCustomData,
},
},
};
}
return {
type: emitResponse.responseTypes.ERROR,
message: 'There was an error',
};
} );
// 当此组件卸载时,取消订阅。
return () => {
unsubscribe();
};
}, [
emitResponse.responseTypes.ERROR,
emitResponse.responseTypes.SUCCESS,
onPaymentProcessing,
] );
return decodeEntities( settings.description || '' );
};
现在,当一个订单被创建时,如果查看 API 请求的负载,我们可以看到以下 JSON:
{
"shipping_address": {},
"billing_address": {},
"customer_note": "",
"create_account": false,
"payment_method": "bacs",
"payment_data": [
{
"key": "myGatewayCustomData",
"value": "12345"
}
],
"extensions": {}
}
一个回调函数 woocommerce_rest_checkout_process_payment_with_context 可以访问这些数据,并将其用于处理支付。
WooCommerce REST API 结账处理流程
本文档描述了使用 WooCommerce REST API 进行结账处理的流程。
结账流程
- 用户在前端通过 REST API 发起结账请求。
- 服务器接收到请求,并验证用户输入的数据。
- 服务器调用相应的
Method处理支付。 - 服务器将
Result返回给前端。
详细步骤
以下是一个示例,展示了如何使用 add_action 钩子来处理 Context 中的自定义数据。
add_action( 'woocommerce_rest_checkout_process_payment_with_context', function( $context, $result ) {
if ( $context->payment_method === 'bacs' ) {
$myGatewayCustomData = $context->payment_data['myGatewayCustomData'];
// 这里我们会使用 $myGatewayCustomData 来处理支付
}
} )
说明:
woocommerce_rest_checkout_process_payment_with_context:一个Action钩子,允许在处理结账支付时访问Context对象。$context:包含用户输入的数据和支付信息的Context对象。$result:包含支付Result的对象。payment_method:支付Method的名称。myGatewayCustomData:一个Custom字段,用于存储自定义数据。
错误处理
如果在 结账 过程中发生错误,服务器应返回一个错误信息给前端。
安全性
请确保对所有用户输入的数据进行验证和过滤,以防止安全漏洞。
示例
以下是一个使用 REST API 进行 支付 的示例:
POST /wp-json/wc/v3/orders
{
"payment_method": {
"method": "bacs",
"myGatewayCustomData": "some custom data"
}
}
注意:
- 请根据实际情况修改代码。
- 请参考 WooCommerce 文档了解更多信息。
Pro版本可能包含更多功能。
术语表
| 英文术语 | 中文术语 |
|---|---|
| Checkout | 结账 |
| Gateway | 网关 |
| Context | 上下文 |
| Method | 方法 |
| check | 检查 |
| Data | 数据 |
| Use | 使用 |
| Result | 结果 |
| Custom | 自定义 |
| Action | 操作 |
| Text | 文本 |
| here | 这里 |
| Pro | 专业版 |
| Pay | 支付 |
| on | 开 |
| at | 在 |
| mm | mm |
| Th | 星期四 |
| Su | 星期日 |
| We | 周三 |
付款方式集成
客户端集成
客户端集成包含用于注册_常规_和_快捷_付款方式的 API。
在这两种情况下,客户端集成都是通过 blocks-registry API 上公开的注册方法完成的。您可以通过 WooCommerce 环境中的 wc 全局变量访问此 API(wc.wcBlocksRegistry)。
注意:在构建过程中,您可以执行类似于区块仓库中所做的操作,将此 API 作为外部依赖别名为
@woocommerce/blocks-registry。
快速支付方式
快速支付方式是指由购物者通过一键支付流程发起的支付方式,例如 Stripe、ApplePay 或 GooglePay。

注册
要注册一个快速支付方法,您需要使用区块注册表中的 registerExpressPaymentMethod 函数。
const { registerExpressPaymentMethod } = window.wc.wcBlocksRegistry;
如果您为 @woocommerce/blocks-registry 使用了别名导入,可以像这样导入该函数:
import { registerExpressPaymentMethod } from '@woocommerce/blocks-registry';
注册函数期望接收一个包含支付方法特定选项的 JavaScript 对象:
registerExpressPaymentMethod( options );
您提供给配置实例的选项应是一个具有以下形状的对象(参见 ExpressPaymentMethodConfiguration 类型定义):
const options = {
name: 'my_payment_method',
title: 'My Mayment Method',
description: 'A setence or two about your payment method',
gatewayId: 'gateway-id',
label: <ReactNode />,
content: <ReactNode />,
edit: <ReactNode />,
canMakePayment: () => true,
paymentMethodId: 'my_payment_method',
supports: {
features: [],
style: [],
},
};
ExpressPaymentMethodConfiguration
| 选项 | 类型 | 描述 | 必需 |
|---|---|---|---|
name |
字符串 | 网关客户端的唯一标识符。 | 是 |
title |
字符串 | 您的支付方式的人性化名称。在编辑器中向商家显示。 | 否 |
description |
字符串 | 描述您的支付网关的简短文字(一到两句话)。在编辑器中向商家显示。 | 否 |
gatewayId |
字符串 | 注册服务器端的支付网关的 ID。用于将商家引导到编辑器中的正确设置页面。如果未提供此 ID,商家将被重定向到 WooCommerce 的常规支付设置页面。 | 否 |
content |
ReactNode | 当在前端渲染块时,在快速支付方式区域输出的 React 节点。从结账支付方式界面接收 props。 | 是 |
edit |
ReactNode | 当在编辑器中渲染块时,在快速支付方式区域输出的 React 节点。从支付方式界面接收 props,用于预览数据。 | 是 |
canMakePayment |
函数 | 回调函数,用于确定该支付方式是否应为用户可用。 | 是 |
paymentMethodId |
字符串 | 伴随发送到服务器的结账处理请求的标识符。用于标识用于处理支付的支付方式网关类。 | 否 |
supports:features |
数组 | 网关支持的支付功能的数组。用于检查该支付方式是否可用于购物车中的商品。如果未提供任何值,则默认为 ['products']。 |
否 |
supports:style |
数组 | 这是一个快速支付方式支持的样式变化数组。这些样式应用于所有活动的快速支付方式按钮,并且可以在编辑器中的快速支付方式块中进行控制。支持的值之一是 ['height', 'borderRadius']。 |
否 |
canMakePayment 选项
canMakePayment 是一个回调函数,用于确定该付款方式是否应作为购物者的可用选项。该函数将接收一个包含当前订单数据的对象。
canMakePayment( {
cart: Cart,
cartTotals: CartTotals,
cartNeedsShipping: boolean,
shippingAddress: CartShippingAddress,
billingAddress: CartBillingAddress,
selectedShippingMethods: Record<string,unknown>,
paymentRequirements: string[],
} )
canMakePayment 返回一个布尔值。如果您的网关需要执行异步初始化来确定可用性,您可以返回一个 Promise(解析为布尔值)。这允许根据购物车隐藏付款方式,例如,如果购物车包含实体/可运输产品(示例:货到付款);或者允许付款方式根据其他条件控制其是否可用。
canMakePayment 仅在商店前端运行。在编辑上下文中,编辑器将假定付款方式可用(true),而不是使用 canMakePayment,以便向商家显示定义的 edit 组件。
请注意,此函数可能在结账生命周期中被多次调用,因此在此属性上提供的回调函数中的任何昂贵逻辑都应进行记忆化处理。
快速付款方式的按钮属性
此 API 提供了一种同步快速支付按钮外观的方法,以实现一致的购物者体验。快速付款方式必须优先使用 buttonAttributes 中提供的值,并在按钮在购物车或结账区块之外渲染时,使用自身的配置设置作为备份。
例如,在您的按钮组件中,您需要执行类似以下操作:
// 获取您的扩展特定设置,并在不可用时设置默认值
let {
borderRadius = '4',
height = '48',
} = getButtonSettingsFromConfig();
// 在购物车和结账区块上下文中,我们会收到 `buttonAttributes` 作为属性,它会覆盖扩展特定设置
if ( typeof buttonAttributes !== 'undefined' ) {
height = buttonAttributes.height;
borderRadius = buttonAttributes.borderRadius;
}
...
return <button style={height: `${height}px`, borderRadius: `${borderRadius}px`} />
付款方式
付款方式是在结账区块中显示的支付方法选项。示例包括_支票_、PayPal 标准和 Stripe 信用卡。

注册
要注册一种付款方式,您可以使用 registerPaymentMethod 函数,该函数位于 blocks 注册表中。
const { registerPaymentMethod } = window.wc.wcBlocksRegistry;
如果您使用别名导入 @woocommerce/blocks-registry,则可以这样导入该函数:
import { registerPaymentMethod } from '@woocommerce/blocks-registry';
注册函数期望一个包含特定于付款方式的选项的 JavaScript 对象:
registerPaymentMethod( options );
您传递给配置实例的选项应该是一个具有以下结构的 对象(请参阅 PaymentMethodRegistrationOptions 类型定义)。 您传递给配置实例的选项与用于快速付款方式的选项相同,但增加了以下内容:
| 属性 | 类型 | 描述 |
|---|---|---|
savedTokenComponent |
ReactNode | 一个 React 节点,包含处理已保存付款方式的逻辑。 当客户选择此付款方式的已保存令牌时,会进行渲染。 |
label |
ReactNode | 一个用于输出付款方式选项标签的 React 节点。 它可以是文本或图像。 |
ariaLabel |
string | 当选择付款方式时,屏幕阅读器读取的标签。 |
placeOrderButtonLabel |
string | 可选标签,用于更改当选择此付款方式时,默认的“提交订单”按钮的文本。 与 placeOrderButton 互斥。 |
placeOrderButton |
React Component | 可选的 React 组件,用于替换当选择此付款方式时,默认的“提交订单”按钮。 与 placeOrderButtonLabel 互斥。 该组件接收 PaymentMethodInterface 属性。 |
supports |
object | 包含关于支持功能的的信息: |
supports.showSavedCards |
boolean | 确定是否向客户显示此付款方式的已保存卡片。 |
supports.showSaveOption |
boolean | 控制是否显示用于将付款方式保存以供将来使用的复选框。 |
使用自定义“提交订单”按钮
您的自定义按钮组件会接收与付款方式 content 组件相同的属性,并通过 PaymentMethodInterface 传递,此外还包含一些与按钮相关的附加属性:
waitingForProcessing- 是否正在处理结账过程。waitingForRedirect- 是否正在等待成功后进行重定向。disabled- 是否应禁用按钮。isEditor- 按钮是否正在块编辑器中渲染。isPreview- 按钮是否正在预览模式下渲染。
以下是一个简单的示例:
const CustomButton = ( props ) => {
const { validate, onSubmit, disabled, isEditor, isPreview, eventRegistration: { onPaymentSetup }, emitResponse } = props;
const [
isShowingInternalPaymentSheet,
setIsShowingInternalPaymentSheet,
] = React.useState( false );
const paymentResultRef = React.useRef( false );
const handleClick = async () => {
// 1. 验证结账表单
const validationResult = await validate();
if ( validationResult.hasError ) {
return; // WooCommerce 会自动显示验证错误
}
// 2. 显示您的付款界面(例如,Google Pay 界面、Apple Pay 界面)
// setIsShowingInternalPaymentSheet( true );
// const paymentResult = await showPaymentSheet( billing.cartTotal.value );
// paymentResultRef.current = paymentResult.success;
// if ( ! paymentResult.success ) {
// setIsShowingInternalPaymentSheet( false );
// return;
// }
// 3. 在收集到所有付款信息后,将结账提交到服务器。
onSubmit();
};
React.useEffect(
() =>
onPaymentSetup( () => {
return ({
type: paymentResultRef.current ? emitResponse.responseTypes.SUCCESS : emitResponse.responseTypes.ERROR,
meta: {
paymentMethodData: {
payment_method: 'your-payment-method',
},
},
});
} ),
[ onPaymentSetup, emitResponse.responseTypes.SUCCESS, emitResponse.responseTypes.ERROR ]
);
// 在编辑器/预览模式下,显示一个占位符或预览版本
if ( isEditor || isPreview ) {
return (
<button type="button" disabled>
使用自定义方式支付 (预览)
</button>
);
}
return (
<button
type="button"
onClick={ handleClick }
disabled={ disabled || isShowingInternalPaymentSheet }
>
{ disabled || isShowingInternalPaymentSheet
? '处理中...'
: '使用自定义方式支付' }
</button>
);
};
**注册自定义付款方式**
本指南介绍了如何注册自定义付款方式。
**内容:**
* **产品:** 自定义付款方式
* **选择:** 注册自定义付款方式
* **按钮:** 注册按钮
* **方法:** `registerPaymentMethod`
* **标签:** 付款方式标签
* **订单:** 订单
* **编辑:** 编辑按钮
* **保存:** 保存按钮
* **显示:** 显示区域
* **列表:** 付款方式列表
* **端口:** 无
* **使用:** 使用指南
* **在:** 在页面中
* **否:** 否
* **付款方式:** 付款方式
* **描述:** 描述信息
* **下单:** 下单按钮
* **已选中:** 已选择状态
```javascript
registerPaymentMethod( {
name: 'my-custom-payment',
label: <div>我的自定义付款方式</div>,
content: <div>付款方式描述</div>,
edit: <div>付款方式描述</div>,
placeOrderButton: CustomButton,
canMakePayment: () => true,
supports: {
features: [ 'products' ],
},
} );
注意: 自定义按钮仅在从列表中选择付款方式时才会显示。 当选择已保存的付款凭证时,将使用默认的“下单”按钮。
传递给付款方式节点的属性
付款方式集成的一个重要部分是,当提供的节点被克隆并在区块挂载时渲染时,会通过属性向付款方式暴露的界面。虽然所有属性都列在下面,但您可以在 此文件中描述的类型定义 中找到有关这些属性引用的对象、它们的类型等的更多详情。
属性说明
| Property | Type | Description |
|---|---|---|
activePaymentMethod |
String | 当前结账流程中活动的付款方式的别名。 |
billing |
包含 billingAddress, cartTotal, currency, cartTotalItems, displayPricesIncludingTax, appliedCoupons, customerId 属性的对象 |
包含所有与账单相关的信息。 |
cartData |
包含 cartItems, cartFees, extensions 属性的对象 |
暴露的购物车数据,包括商品、费用以及任何已注册的扩展数据。 请注意,这些数据应被视为不可变的(不应修改),否则会导致应用程序出现错误。 |
checkoutStatus |
包含 isCalculating, isComplete, isIdle, isProcessing 属性的对象 |
以各种布尔状态暴露的当前结账状态。 |
components |
包含 ValidationInputError, PaymentMethodLabel, PaymentMethodIcons, LoadingMask 属性的对象 |
暴露 React 组件,这些组件可以由您的付款方式用于各种常见的付款方式界面元素。 |
emitResponse |
包含 noticeContexts 和 responseTypes 属性的对象 |
包含一些常量,在事件发射器中使用时可能很有用。 请阅读 事件发射 部分以获取更多详细信息。 |
eventRegistration |
包含 onCheckoutValidation, onCheckoutSuccess, onCheckoutFail, onPaymentSetup, onShippingRateSuccess, onShippingRateFail, onShippingRateSelectSuccess, onShippingRateSelectFail 属性的对象 |
包含所有结账事件发射器注册函数。 这些是付款方式可以注册观察者以与结账流程的各个阶段进行交互的函数(请参阅 此文档 以获取更多信息)。 |
onClick |
Function | 提供给表达付款方式,当付款方式按钮被点击时触发(这将向结账发出信号,表明付款方式已接管付款处理)。 |
onClose |
Function | 提供给表达付款方式,当快速付款方式模态框关闭并控制权返回到结账时触发。 |
onSubmit |
Function | 提交结账并开始处理。 |
validate |
Function | 异步函数,用于在不提交的情况下验证结账表单。 返回一个解析为 { hasError: boolean } 的 Promise。 当您需要在显示付款方式之前进行验证时,此功能很有用。 |
buttonAttributes |
包含 height, borderRadius 属性的对象 |
由商家设置的样式,所有快速付款方式按钮都应遵守这些样式。 |
paymentStatus |
Object | 各种付款状态辅助函数。 请注意,您的付款方式不必在客户端设置此状态。 结账将通过您的付款方式从注册到 结账事件发射器 的回复来处理此操作。 |
paymentStatus.isPristine |
Boolean | 当当前付款状态为 PRISTINE 时,此值为 true。 |
paymentStatus.isStarted |
Boolean | 当当前付款状态为 EXPRESS_STARTED 时,此值为 true。 |
paymentStatus.isProcessing |
Boolean | 当当前付款状态为 PROCESSING 时,此值为 true。 |
paymentStatus.isFinished |
Boolean | 当当前付款状态为 ERROR, FAILED 或 SUCCESS 中的任何一个时,此值为 true。 |
paymentStatus.hasError |
Boolean | 当当前付款状态为 ERROR 时,此值为 true。 |
paymentStatus.hasFailed |
Boolean | 当当前付款状态为 FAILED 时,此值为 true。 |
paymentStatus.isSuccessful |
Boolean | 当当前付款状态为 SUCCESS 时,此值为 true。 |
setExpressPaymentError |
Function | 接收一个字符串,允许快速付款方式在需要时为快速付款区域设置错误通知。 这可能是必要的,因为某些快速付款方式的处理可能发生在结账事件之外。 |
shippingData |
包含 shippingRates, shippingRatesLoading, selectedRates, setSelectedRates, isSelectingRate, shippingAddress, setShippingAddress, needsShipping 属性的对象 |
包含所有与运输相关的数据(不包括运输状态)。 |
shippingStatus |
包含 shippingErrorStatus, shippingErrorTypes 属性的对象 |
各种运输状态辅助函数。 |
shouldSavePayment |
Boolean | 指示购物者是否选择保存其付款方式详细信息(适用于支持保存付款方式的付款方式)。 如果已选择,则为 true;否则为 false。 默认为 false。 |
任何已注册的 savedTokenComponent 节点也会接收一个 token 属性,该属性包含所选择的已保存令牌的 ID,以备您的支付方法需要将其用于某些内部逻辑。但是,请记住,这只是代表该令牌在数据库中的 ID(以及购物者选中的单选框的值),而不是实际的客户支付令牌(因为通常在服务器上进行处理以确保安全)。
服务器端集成
对于服务器端集成,您需要创建一个类,该类需要继承 Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType 类。
这个类是您付款方式的服务器端表示。它用于在正确的时间,将您的付款方式资源注册到商店 API 和结账模块。它与您需要单独实现的 支付网关 API 不同,后者用于处理支付。
示例支付方式集成类
<?php
namespace MyPlugin\MyPaymentMethod;
use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType;
final class MyPaymentMethodType extends AbstractPaymentMethodType {
/**
* 此属性是一个字符串,用于引用您的支付方式。 重要的是要使用与客户端 JavaScript 支付方式注册中相同的名称。
*
* @var string
*/
protected $name = 'my_payment_method';
/**
* 初始化支付方式。
*
* 此函数将在服务器端初始化过程中被调用,并且是放置任何设置等内容的理想位置。 基本上,您需要做任何事情来初始化您的网关。
*
* 请注意,此函数将在每个请求中被调用,因此请不要在此处放置任何耗时操作。
*/
public function initialize() {
$this->settings = get_option( 'woocommerce_my_payment_method_settings', [] );
}
/**
* 此函数应返回支付方式是否处于活动状态。
*
* 如果为 false,则不会加载脚本。
*
* @return boolean
*/
public function is_active() {
return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN );
}
/**
* 返回一个要注册的脚本/句柄的数组,用于此支付方式。
*
* 在此函数中,您应该注册您的支付方式脚本(使用 `wp_register_script`),然后返回您注册的脚本句柄。 这将用于将您的支付方式作为结账脚本的依赖项,从而确保正确加载它。
*
* 请注意,您仍然应该确保您的脚本具有的其他任何资源依赖项都已在此处正确注册。 如果您使用 Webpack 构建资源,您可能希望使用 WooCommerce Webpack 依赖项提取插件
* (https://www.npmjs.com/package/@woocommerce/dependency-extraction-webpack-plugin) 来使此过程更容易。
*
* @return array
*/
public function get_payment_method_script_handles() {
wp_register_script(
'my-payment-method',
'path/to/your/script/my-payment-method.js',
[],
'1.0.0',
true
);
return [ 'my-payment-method' ];
}
/**
* 返回一个要为管理后台排队的脚本句柄的数组。
*
* 如果您的支付方式有一个脚本,您_只想_在结账块的编辑器上下文加载,则包含此脚本。
* 将 `get_payment_method_script_handles` 中的任何脚本也包含在此处,如果它们也需要在管理后台加载。
*/
public function get_payment_method_script_handles_for_admin() {
return $this->get_payment_method_script_handles();
}
/**
* 返回一个键值对数组,这些数据可供付款方式脚本客户端使用。
*
* 这些数据可以通过 `wc.wcSettings.getSetting` 在客户端访问。例如,如果您将 `stripe` 赋值为该类的 `name` 属性,则可以在客户端通过以下方式访问任何数据:
* `wc.wcSettings.getSetting( 'stripe_data' )`。这将返回一个对象,其形状与您从此函数返回的关联数组匹配。
*
* @return array
*/
public function get_payment_method_data() {
return [
'title' => $this->get_setting( 'title' ),
'description' => $this->get_setting( 'description' ),
'supports' => $this->get_supported_features(),
];
}
}
文档
这是一个示例文档,其中包含一些常用的术语。
设置
- Settings → 设置
- Payment methods → 付款方式
- Available → 可用
- Property → 属性
- Method → 方法
- Access → 访问
- Title → 标题
- Value → 价值
- Shape → 形状
- Class → 类
- Data → 数据
- Port → 端口
- Via → 通过
- Key → 关键字
- For → 为
- Tan → 褐色
- Cc → 抄送
- In → 在
- Description → 描述
- Assigned → 已分配
示例
这是一个示例段落,演示如何使用上述术语。
例如,您可以在 设置 中配置 付款方式。每个 付款方式 都有自己的 属性 和 方法。您可以通过 访问 相应的 端口 来获取 数据。
列表
以下是一个列表,其中包含一些常用的命令:
command1command2command3
代码示例
以下是一个代码示例,演示如何使用 get_payment_method_data 函数:
/**
* Returns an array of key=>value pairs of data made available to the payment methods script client side.
*
* This data will be available client side via `wc.wcSettings.getSetting`. So for instance if you assigned `stripe` as the
* value of the `name` property for this class, client side you can access any data via:
* `wc.wcSettings.getSetting( 'stripe_data' )`. That would return an object matching the shape of the associative array
* you returned from this function.
*
* @return array
*/
public function get_payment_method_data() {
return [
'title' => $this->get_setting( 'title' ),
'description' => $this->get_setting( 'description' ),
'supports' => $this->get_supported_features(),
];
}
}
占位符和 HTML 标签
以下是一个包含占位符和 HTML 标签的示例:
This is a string with a placeholder: %s.
<p>This is a paragraph.</p>
URL 链接
以下是一个 URL 链接:
函数名、变量名、命令名
函数名、变量名和命令名应保持英文原文。例如:MyFunction, myVariable, myCommand.
### 注册付款方式集成
在创建了继承 `Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType` 的类后,您需要将其注册到服务器端的付款方式处理中。
您可以通过使用 `PaymentMethodRegistry` 类上的 `register` 方法来实现。
```php
use MyPlugin\MyPaymentMethod\MyPaymentMethodType;
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
add_action(
'woocommerce_blocks_payment_method_type_registration',
function( PaymentMethodRegistry $payment_method_registry ) {
$payment_method_registry->register( new MyPaymentMethodType() );
}
);
处理支付(旧版支持)
支付仍通过支付网关 API 处理。这是一个独立于上述付款方式集成所使用的 API。
结账区块将客户端脚本提供的 payment_data 转换为 $_POST 并调用支付网关的 process_payment 方法。
如果您已有一个与短代码结账流程集成的 WooCommerce 支付方法扩展,旧版处理机制将在服务器端为您处理支付。
通过商店 API 处理支付
在某些更高级的场景下,之前提到的旧版支付处理方式可能无法满足您现有的支付方式集成需求。对于这些情况,还提供了一个动作钩子,您可以使用它来处理服务器端的订单处理,它提供了更多的上下文信息,并且专用于商店 API。
这个钩子是集成支付处理的首选位置:
do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$result ] );
注意:在您之前创建的支付方式类型类的
initialize方法中注册您的回调函数是一个不错的选择。
在该钩子上注册的回调函数将接收到:
- 一个
PaymentContext对象,其中包含所选的payment_method(这与在注册支付方式时定义的paymentMethodId值相同),正在创建的order,以及由支付方式客户端提供的任何额外的payment_data。 - 一个
PaymentResult对象,您可以使用它来通过商店 API 将状态、重定向 URL 以及任何其他支付详情返回给客户端。
如果您在提供的 PaymentResult 对象上设置了状态,则您的支付方式将不再使用旧版支付处理方式。如果发生错误,您的回调函数可以抛出异常,该异常将由商店 API 处理。
以下是一个示例回调函数:
add_action(
'woocommerce_rest_checkout_process_payment_with_context',
function( $context, $result ) {
if ( $context->payment_method === 'my_payment_method' ) {
// 订单处理逻辑将在此处执行!
// $context->order 包含订单对象,如果需要
// ...
// 如果上述逻辑成功,我们可以将状态设置为成功。
$result->set_status( 'success' );
$result->set_payment_details(
array_merge(
$result->payment_details,
[
'custom-data' => '12345',
]
)
);
$result->set_redirect_url( 'some/url/to/redirect/to' );
}
},
10,
2
);
从客户端传递值到服务器端支付处理
在这个例子中,我们将从 BACS 支付方法传递一些数据到服务器。BACS 的注册过程大致如下:
// 获取在注册支付方法时提供的设置
const settings = window.wc.wcSettings.getSetting( 'bacs_data' );
// 这是一个组件,当选择 BACS 支付方法时,它将在结账块中渲染
const Content = () => {
return decodeEntities( settings?.description || '' );
};
// 这是一个支付方法的标签
const Label = ( props ) => {
const { PaymentMethodLabel } = props.components;
return <PaymentMethodLabel text={ decodeEntities( settings?.title || 'BACS' ) } />;
};
// 注册支付方法
const bankTransferPaymentMethod = {
name: 'BACS',
label: <Label />,
content: <Content />,
edit: <Content />,
canMakePayment: () => true,
supports: {
features: settings?.supports ?? [],
},
};
支付方法节点会传递所有数据,这些数据来自 usePaymentMethodInterface 钩子。因此,我们可以在我们的 <Content /> 组件中使用它,如下所示:
const Content = ( props ) => {
const { eventRegistration, emitResponse } = props;
const { onPaymentProcessing } = eventRegistration;
useEffect( () => {
const unsubscribe = onPaymentProcessing( async () => {
// 可以在这里执行任何需要的处理,然后发出响应。
// 例如,我们可以验证一个自定义字段,或者执行一个 AJAX 请求,然后发出一个响应,指示其是否有效。
const myGatewayCustomData = '12345';
const customDataIsValid = !! myGatewayCustomData.length;
if ( customDataIsValid ) {
return {
type: emitResponse.responseTypes.SUCCESS,
meta: {
paymentMethodData: {
myGatewayCustomData,
},
},
};
}
return {
type: emitResponse.responseTypes.ERROR,
message: 'There was an error',
};
} );
// 当此组件卸载时,取消订阅。
return () => {
unsubscribe();
};
}, [
emitResponse.responseTypes.ERROR,
emitResponse.responseTypes.SUCCESS,
onPaymentProcessing,
] );
return decodeEntities( settings.description || '' );
};
现在,当一个订单被创建时,如果查看 API 请求的负载,我们可以看到以下 JSON:
{
"shipping_address": {},
"billing_address": {},
"customer_note": "",
"create_account": false,
"payment_method": "bacs",
"payment_data": [
{
"key": "myGatewayCustomData",
"value": "12345"
}
],
"extensions": {}
}
一个回调函数 woocommerce_rest_checkout_process_payment_with_context 可以访问这些数据,并将其用于处理支付。
WooCommerce REST API 结账处理流程
本文档描述了使用 WooCommerce REST API 进行结账处理的流程。
结账流程
- 用户在前端通过 REST API 发起结账请求。
- 服务器接收到请求,并验证用户输入的数据。
- 服务器调用相应的
Method处理支付。 - 服务器将
Result返回给前端。
详细步骤
以下是一个示例,展示了如何使用 add_action 钩子来处理 Context 中的自定义数据。
add_action( 'woocommerce_rest_checkout_process_payment_with_context', function( $context, $result ) {
if ( $context->payment_method === 'bacs' ) {
$myGatewayCustomData = $context->payment_data['myGatewayCustomData'];
// 这里我们会使用 $myGatewayCustomData 来处理支付
}
} )
说明:
woocommerce_rest_checkout_process_payment_with_context:一个Action钩子,允许在处理结账支付时访问Context对象。$context:包含用户输入的数据和支付信息的Context对象。$result:包含支付Result的对象。payment_method:支付Method的名称。myGatewayCustomData:一个Custom字段,用于存储自定义数据。
错误处理
如果在 结账 过程中发生错误,服务器应返回一个错误信息给前端。
安全性
请确保对所有用户输入的数据进行验证和过滤,以防止安全漏洞。
示例
以下是一个使用 REST API 进行 支付 的示例:
POST /wp-json/wc/v3/orders
{
"payment_method": {
"method": "bacs",
"myGatewayCustomData": "some custom data"
}
}
注意:
- 请根据实际情况修改代码。
- 请参考 WooCommerce 文档了解更多信息。
Pro版本可能包含更多功能。
术语表
| 英文术语 | 中文术语 |
|---|---|
| Checkout | 结账 |
| Gateway | 网关 |
| Context | 上下文 |
| Method | 方法 |
| check | 检查 |
| Data | 数据 |
| Use | 使用 |
| Result | 结果 |
| Custom | 自定义 |
| Action | 操作 |
| Text | 文本 |
| here | 这里 |
| Pro | 专业版 |
| Pay | 支付 |
| on | 开 |
| at | 在 |
| mm | mm |
| Th | 星期四 |
| Su | 星期日 |
| We | 周三 |
内部区块类型
以下“附加购物车和结账”内部区块类型过滤器可用:
additionalCartCheckoutInnerBlockTypes
additionalCartCheckoutInnerBlockTypes
描述
购物车和结账区块由内部区块组成。这些内部区块区域允许添加特定类型的区块作为子区块。默认情况下,只有 core/paragraph、core/image 和 core/separator 可用。
通过使用 additionalCartCheckoutInnerBlockTypes 过滤器,可以将项目添加到此数组中,以控制编辑器可以在哪些内部区块中添加内容。
此过滤器为每个内部区块区域调用一次,因此在确定可以在哪里添加哪些区块时,可以进行非常细粒度的控制。
参数
- defaultValue
array(默认值:[]) - 过滤器的默认值。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- block
string- 内部区块区域的区块名称,例如:woocommerce/checkout-shipping-address-block。
- block
- validation
boolean或Error- 检查返回的值是否为字符串数组。如果发生错误,则会抛出错误。
返回值
array- 包含允许的区块类型的修改后的数组,适用于相应的内部区块区域。
代码示例
假设我们希望允许编辑器在购物车和结账区块的特定位置添加某些区块。
- 允许在购物车和结账区块的每个区块区域中插入
core/quote。 - 允许在结账中的“配送地址”区块中插入
core/table。
在我们的扩展中,我们可以注册一个过滤器来满足这两个条件,如下所示:
document.addEventListener( 'DOMContentLoaded', function () {
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyAdditionalInnerBlockTypes = (
defaultValue,
extensions,
args,
validation
) => {
defaultValue.push( 'core/quote' );
if ( args?.block === 'woocommerce/checkout-shipping-address-block' ) {
defaultValue.push( 'core/table' );
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
additionalCartCheckoutInnerBlockTypes: modifyAdditionalInnerBlockTypes,
} );
} );
要在编辑器中调用此过滤器,请将过滤器注册包含在 DOMContentLoaded 事件监听器中,并确保代码在管理面板中运行。
过滤器也可以组合使用。请参阅 组合过滤器,以获取示例。
截图
| 前 | 后 |
|---|---|
购物车明细项
以下购物车明细项过滤器是可用的:
cartItemClasscartItemPriceitemNamesaleBadgePriceFormatshowRemoveItemLinksubtotalPriceFormat
以下对象在过滤器之间共享:
- 购物车对象
- 购物车明细项对象
以下截图显示了各个过滤器影响的部分:

cartItemClass
描述
cartItemClass 过滤器允许修改购物车明细项的类。
参数
- defaultValue
object(默认值:'') - 购物车明细项的默认类。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅 购物车对象。 - cartItem
object- 来自wc/store/cart的购物车明细项对象,请参阅 购物车明细项对象。 - context
string(允许的值:cart或summary) - 物品的上下文。
- cart
返回值
string- 修改后的购物车明细项类,或一个空字符串。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemClass = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return 'my-custom-class';
};
registerCheckoutFilters( 'example-extension', {
cartItemClass: modifyCartItemClass,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemClass = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return 'cool-class';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return 'hot-class';
}
return 'my-custom-class';
};
registerCheckoutFilters( 'example-extension', {
cartItemClass: modifyCartItemClass,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 之前 | 之后 |
|---|---|
cartItemPrice
描述
cartItemPrice 过滤器允许格式化购物车项目价格。
参数
- defaultValue
string(默认值:<price/>) - 购物车项目的默认价格。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅购物车对象。 - cartItem
object- 来自wc/store/cart的购物车项目对象,请参阅购物车项目对象。 - context
string(允许的值:cart或summary) - 项目的上下文。
- cart
- validation
boolean- 检查返回值是否包含子字符串<price/>。
返回值
string- 购物车项目价格的修改后的格式,必须包含子字符串<price/>,或者原始的价格格式。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemPrice = ( defaultValue, extensions, args, validation ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return '<price/> for all items';
};
registerCheckoutFilters( 'example-extension', {
cartItemPrice: modifyCartItemPrice,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemPrice = ( defaultValue, extensions, args, validation ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return '<price/> to keep you warm';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return '<price/> to keep you cool';
}
return '<price/> for all items';
};
registerCheckoutFilters( 'example-extension', {
cartItemPrice: modifyCartItemPrice,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 之前 | 之后 |
|---|---|
itemName
描述
itemName 过滤器允许修改购物车商品名称。
参数
- defaultValue
string- 购物车商品的默认名称。 - extensions
object(默认:{}) - 扩展对象。 - args
object- 参数对象,包含以下键:- cart
object- 来自wc/store/cart的购物车对象,请参阅购物车对象。 - cartItem
object- 来自wc/store/cart的购物车商品对象,请参阅购物车商品对象。 - context
string(允许的值:cart或summary) - 商品的上下文。
- cart
返回值
string- 原始或修改后的购物车商品名称。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyItemName = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return `🪴 ${ defaultValue } 🪴`;
};
registerCheckoutFilters( 'example-extension', {
itemName: modifyItemName,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyItemName = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return `⛷️ ${ defaultValue } ⛷️`;
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return `🏄♂️ ${ defaultValue } 🏄♂️`;
}
return `🪴 ${ defaultValue } 🪴`;
};
registerCheckoutFilters( 'example-extension', {
itemName: modifyItemName,
} );
过滤器也可以组合使用。请参阅 组合过滤器 了解示例。
截图
| 之前 | 之后 |
|---|---|
saleBadgePriceFormat
描述
saleBadgePriceFormat 过滤器允许格式化购物车中商品的促销徽章价格。
参数
- defaultValue
string(默认值:<price/>) - 购物车中商品默认的促销徽章价格。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅购物车对象。 - cartItem
object- 来自wc/store/cart的购物车商品对象,请参阅购物车商品对象。 - context
string(允许的值:cart或summary) - 商品的上下文。
- cart
- validation
boolean- 检查返回值是否包含子字符串<price/>。
返回值
string- 购物车中商品促销徽章价格的修改后的格式,必须包含子字符串<price/>,或者原始的价格格式。
代码示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySaleBadgePriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
saleBadgePriceFormat: modifySaleBadgePriceFormat,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySaleBadgePriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return '<price/> per item while keeping warm';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return '<price/> per item while looking cool';
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
saleBadgePriceFormat: modifySaleBadgePriceFormat,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 之前 | 之后 |
|---|---|
showRemoveItemLink
描述
showRemoveItemLink 用于显示或隐藏购物车中商品的移除链接。
参数
- defaultValue (类型:
boolean, 默认值:true) - 移除链接的默认值。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 参数对象,包含以下键:- cart
object- 来自wc/store/cart的购物车对象,请参阅购物车对象。 - cartItem
object- 来自wc/store/cart的购物车商品对象,请参阅购物车商品对象。 - context
string(允许的值:cart或summary) - 商品的上下文。
- cart
返回值
boolean- 如果应该显示购物车商品移除链接,则返回true,否则返回false。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowRemoveItemLink = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return false;
};
registerCheckoutFilters( 'example-extension', {
showRemoveItemLink: modifyShowRemoveItemLink,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowRemoveItemLink = ( defaultValue, extensions, args ) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return false;
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return false;
}
return true;
};
registerCheckoutFilters( 'example-extension', {
showRemoveItemLink: modifyShowRemoveItemLink,
} );
过滤器也可以组合使用。请参阅 组合过滤器 了解示例。
屏幕截图
| 之前 | 之后 |
|---|---|
subtotalPriceFormat
描述
subtotalPriceFormat 过滤器允许格式化购物车中商品的子总价。
参数
- defaultValue
string(默认值:<price/>) - 购物车中商品的默认子总价。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 参数对象,包含以下键:- cart
object- 来自wc/store/cart的购物车对象,请参阅购物车对象。 - cartItem
object- 来自wc/store/cart的购物车商品对象,请参阅购物车商品对象。 - context
string(允许的值:cart或summary) - 商品的上下文。
- cart
- validation
boolean- 检查返回值是否包含子字符串<price/>。
返回值
string- 购物车中商品子总价的修改后的格式,必须包含子字符串<price/>,或者原始的价格格式。
代码示例
基本示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySubtotalPriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
subtotalPriceFormat: modifySubtotalPriceFormat,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySubtotalPriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isCartContext = args?.context === 'cart';
if ( ! isCartContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return '<price/> per warm beanie';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return '<price/> per cool sunglasses';
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
subtotalPriceFormat: modifySubtotalPriceFormat,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 前面 | 后面 |
|---|---|
购物车对象
上面筛选器的购物车对象具有以下关键字:
规则:
1. 翻译所有英文文本,包括标题、段落、列表项
2. 保持 Markdown 格式不变(#、**、``、[]() 等)
3. 代码块(```...```)内的代码不翻译,只翻译代码块外的文本
4. 保留所有占位符(%s, %d, {name})和 HTML 标签
5. 保留所有 URL 链接地址不翻译
6. 函数名、变量名、命令名保留英文原文
7. 只输出翻译结果,不要输出解释或原文
术语表(必须使用以下译法):
- String → 字符串
- Error → 错误
- Billing Address → 账单地址
- Currency Symbol → 货币符号
- Currency Code → 货币代码
- Total Price → 总价
- First name → 名
- Extensions → 扩展
- Last Name → 姓氏
- Discount → 折扣
- Currency → 货币
- Shipping → 配送
- Address → 地址
- Product → 产品
- Second → 秒
- Prefix → 前缀
- Suffix → 后缀
- number → 数值
- Coupon → 优惠券
- Rates → 费率
- _billingAddress_ `object` - 账单地址对象,包含以下键:
- _address_1_ `string` - 地址的第一行。
- _address_2_ `string` - 地址的第二行。
- _city_ `string` - 地址的城市。
- _company_ `string` - 地址的公司名称。
- _country_ `string` - 地址的国家。
- _email_ `string` - 地址的电子邮件。
- _first_name_ `string` - 地址的称呼。
- _last_name_ `string` - 地址的姓氏。
- _phone_ `string` - 地址的电话号码。
- _postcode_ `string` - 地址的邮政编码。
- _state_ `string` - 地址的省份/州。
- ~~_billingData_~~ `object` - 账单数据对象,包含与 `billingAddress` 对象相同的键。
- _cartCoupons_ `array` - 购物车优惠券数组。
- _cartErrors_ `array` - 购物车错误数组。
- _cartFees_ `array` - 购物车费用数组。
- _cartHasCalculatedShipping_ `boolean` - 是否已计算购物车运费。
- _cartIsLoading_ `boolean` - 购物车是否正在加载。
- _cartItemErrors_ `array` - 购物车商品错误数组。
- _cartItems_ `array` - 购物车商品数组,包含购物车商品对象,请参考购物车商品对象。
- _cartItemsCount_ `number` - 购物车商品数量。
- _cartItemsWeight_ `number` - 购物车商品重量。
- _cartNeedsPayment_ `boolean` - 购物车是否需要支付。
- _cartNeedsShipping_ `boolean` - 购物车是否需要配送。
- _cartTotals_ `object` - 购物车总计对象,包含以下键:
- _currency_code_ `string` - 货币代码。
- _currency_decimal_separator_ `string` - 货币小数分隔符。
- _currency_minor_unit_ `number` - 货币最小单位。
- _currency_prefix_ `string` - 货币前缀。
- _currency_suffix_ `string` - 货币后缀。
- _currency_symbol_ `string` - 货币符号。
- _currency_thousand_separator_ `string` - 货币千位分隔符。
- _tax_lines_ `array` - 税收明细数组,包含税收明细对象,包含以下键:
- _name_ `string` - 税收明细名称。
- _price_ `number` - 税收明细价格。
- _rate_ `string` - 税收明细费率 ID。
- _total_discount_ `string` - 总折扣。
- _total_discount_tax_ `string` - 总折扣税额。
- _total_fees_ `string` - 总费用。
- _total_fees_tax_ `string` - 总费用税额。
- _total_items_ `string` - 总商品数量。
- _total_items_tax_ `string` - 总商品数量税额。
- _total_price_ `string` - 总价。
- _total_shipping_ `string` - 总运费。
- _total_shipping_tax_ `string` - 总运费税额。
- _total_tax_ `string` - 总税额。
- _crossSellsProducts_ `array` - 推荐商品数组,包含推荐商品对象。
- _extensions_ `object` (default: `{}`) - 扩展对象。
- _isLoadingRates_ `boolean` - 购物车是否正在加载配送费率。
- _paymentRequirements_ `array` - 支付要求数组。
- _shippingAddress_ `object` - 配送地址对象,包含与 `billingAddress` 对象相同的键。
- _shippingRates_ `array` - 配送费率数组。
购物车项目对象
上面筛选器中的购物车项目对象具有以下关键字:
项目详情
以下是项目详情的字段说明:
- backorders_allowed
boolean- 是否允许 延期交货。 - catalog_visibility
string- 目录可见性。 - decsription
string- 购物车项目描述。 - extensions
object(default:{}) - 扩展对象。 - id
number- 项目 ID。 - images
array- 项目 图像 数组。 - item_data
array- 项目数据数组。 - key
string- 项目键。 - low_stock_remaining
number- 剩余的低库存数量。 - name
string- 项目 名称。 - permalink
string- 项目 固定链接。 - prices
object- 项目价格对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - price
string- 价格。 - price_range
string- 价格范围。 - raw_prices
object- 原始价格对象,包含以下键:- precision
number- 精度。 - price
number- 价格。 - regular_price
number- 常规价格。 - sale_price
number- 促销价格。
- precision
- regular_price
string- 常规价格。 - sale_price
string- 促销价格。
- currency_code
- quantity
number- 项目 数量。 - quantity_limits
object- 项目数量限制对象,包含以下键:- editable
boolean- 是否可编辑数量。 - maximum
number- 最大数量。 - minimum
number- 最小数量。 - multiple_of
number- 数量的倍数。
- editable
- short_description
string- 项目简短描述。 - show_backorder_badge
boolean- 是否显示 延期交货 徽章。 - sku
string- 项目 SKU。 - sold_individually
boolean- 是否单独销售项目。 - totals
object- 项目总计对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - line_subtotal
string- 行 小计。 - line_subtotal_tax
string- 行 小计 税。 - line_total
string- 行总计。 - line_total_tax
string- 行总计税。
- currency_code
- type
string- 项目类型。 - variation
array- 项目 变体 数组。
结账和下单按钮
以下“结账和下单”按钮过滤器可用:
proceedToCheckoutButtonLabelproceedToCheckoutButtonLinkplaceOrderButtonLabel
以下对象在过滤器之间共享:
- 购物车对象
- 购物车项目对象
proceedToCheckoutButtonLabel
描述
proceedToCheckoutButtonLabel 过滤器允许修改“继续结账”按钮的标签。
参数
- defaultValue
string(默认值:Proceed to Checkout) - “继续结账”按钮的标签。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅 购物车对象。
- cart
返回值
string- “继续结账”按钮的标签。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyProceedToCheckoutButtonLabel = (
defaultValue,
extensions,
args
) => {
if ( ! args?.cart.items ) {
return defaultValue;
}
return 'Go to checkout';
};
registerCheckoutFilters( 'example-extension', {
proceedToCheckoutButtonLabel: modifyProceedToCheckoutButtonLabel,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyProceedToCheckoutButtonLabel = (
defaultValue,
extensions,
args
) => {
if ( ! args?.cart.items ) {
return defaultValue;
}
const isSunglassesInCart = args?.cart.items.some(
( item ) => item.name === 'Sunglasses'
);
if ( isSunglassesInCart ) {
return '😎 Proceed to checkout 😎';
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
proceedToCheckoutButtonLabel: modifyProceedToCheckoutButtonLabel,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 之前 | 之后 |
|---|---|
proceedToCheckoutButtonLink
描述
proceedToCheckoutButtonLink 过滤器允许修改“继续结账”按钮的链接。
参数
_defaultValue_string(默认值:/checkout) - "继续结账" 按钮的链接。_extensions_object(默认值:{}) - 扩展对象。_args_object- 包含以下键的参数对象:_cart_object- 来自wc/store/cart的购物车对象,请参阅 购物车对象。
返回值
string- "继续结账" 按钮的链接。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyProceedToCheckoutButtonLink = (
defaultValue,
extensions,
args
) => {
if ( ! args?.cart.items ) {
return defaultValue;
}
return '/custom-checkout';
};
registerCheckoutFilters( 'example-extension', {
proceedToCheckoutButtonLink: modifyProceedToCheckoutButtonLink,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyProceedToCheckoutButtonLink = (
defaultValue,
extensions,
args
) => {
if ( ! args?.cart.items ) {
return defaultValue;
}
const isSunglassesInCart = args?.cart.items.some(
( item ) => item.name === 'Sunglasses'
);
if ( isSunglassesInCart ) {
return '/custom-checkout';
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
proceedToCheckoutButtonLink: modifyProceedToCheckoutButtonLink,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| Before | After |
|---|---|
placeOrderButtonLabel
描述
参数
_defaultValue_(类型:string, 默认值:Place order) - "提交订单" 按钮的标签。_extensions_object(默认值:{}) - 扩展对象。
返回值
string- "提交订单" 按钮的标签。
代码示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyPlaceOrderButtonLabel = (defaultValue, extensions) => {
return '😎 立即付款 😎';
};
registerCheckoutFilters('example-extension', {
placeOrderButtonLabel: modifyPlaceOrderButtonLabel,
} );
过滤器也可以组合使用。请参阅 组合过滤器 示例。
截图
| 前 (Before) | 后 (After) |
|---|---|
购物车对象
上面筛选器的购物车对象具有以下关键字:
购物车对象
以下描述了购物车对象的结构。
billingAddress object - 账单地址对象,包含以下键:
- address_1 string - 地址的第一行。
- address_2 string - 地址的第二行。
- city string - 地址的城市。
- company string - 地址的公司名称。
- country string - 地址的国家。
- email string - 地址的电子邮件。
- first_name string - 地址的名。
- last_name string - 地址的姓氏。
- phone string - 地址的电话号码。
- postcode string - 地址的邮政编码。
- state string - 地址的州/省。
coupons array - 优惠券数组。
crossSells array - 推荐商品数组。
errors array - 错误数组。
extensions object (default: {}) - 扩展对象。
fees array - 费用数组。
hasCalculatedShipping boolean - 是否已计算配送费用。
items array - 购物车商品数组,包含购物车商品对象,请参考 购物车商品对象。
itemsCount number - 购物车中的商品数量。
itemsWeight number - 购物车商品的总重量。
needsPayment boolean - 是否需要支付。
needsShipping boolean - 是否需要配送。
paymentMethods array - 付款方式数组。
paymentRequirements array - 付款要求数组。
shippingAddress object - 配送地址对象,包含与账单地址对象相同的键。
shippingRates array - 配送费率数组。
totals object - 总价对象,包含以下键:
- currency_code string - 货币代码。
- currency_decimal_separator string - 货币小数分隔符。
- currency_minor_unit number - 货币最小单位。
- currency_prefix string - 货币前缀。
- currency_suffix string - 货币后缀。
- currency_symbol string - 货币符号。
- currency_thousand_separator string - 货币千位分隔符。
- tax_lines array - 税收明细数组,包含对象,每个对象包含以下键:
- name string - 税收名称。
- price string - 税收价格。
- rate string - 税率。
- total_discount string - 总折扣。
- total_discount_tax string - 总折扣税额。
- total_fee string - 总费用。
- total_fee_tax string - 总费用税额。
- total_items string - 商品总价。
- total_items_tax string - 商品总价税额。
- total_price string - 总价。
- total_shipping string - 总配送费用。
- total_shipping_tax string - 总配送费用税额。
- total_tax string - 总税额。
购物车项目对象
上面筛选器中的购物车项目对象具有以下关键字:
项目详情
以下是项目详情的字段说明:
- backorders_allowed
boolean- 是否允许 延期交货。 - catalog_visibility
string- 目录可见性。 - decsription
string- 购物车项目描述。 - extensions
object(default:{}) - 扩展对象。 - id
number- 项目 ID。 - images
array- 项目 图像 数组。 - item_data
array- 项目数据数组。 - key
string- 项目键。 - low_stock_remaining
number- 剩余的低库存数量。 - name
string- 项目 名称。 - permalink
string- 项目 固定链接。 - prices
object- 项目价格对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - price
string- 价格。 - price_range
string- 价格范围。 - raw_prices
object- 原始价格对象,包含以下键:- precision
number- 精度。 - price
number- 价格。 - regular_price
number- 常规价格。 - sale_price
number- 促销价格。
- precision
- regular_price
string- 常规价格。 - sale_price
string- 促销价格。
- currency_code
- quantity
number- 项目 数量。 - quantity_limits
object- 项目数量限制对象,包含以下键:- editable
boolean- 是否可编辑数量。 - maximum
number- 最大数量。 - minimum
number- 最小数量。 - multiple_of
number- 数量的倍数。
- editable
- short_description
string- 项目简短描述。 - show_backorder_badge
boolean- 是否显示 延期交货 徽章。 - sku
string- 项目 SKU。 - sold_individually
boolean- 是否单独销售项目。 - totals
object- 项目总计对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - line_subtotal
string- 行 小计。 - line_subtotal_tax
string- 行 小计 税。 - line_total
string- 行总计。 - line_total_tax
string- 行总计税。
- currency_code
- type
string- 项目类型。 - variation
array- 项目 变体 数组。
优惠券
以下优惠券过滤器可用:
couponsshowApplyCouponNoticeshowRemoveCouponNotice
coupons
描述
当前功能是在购物车和结账侧边栏中显示优惠券代码。 如果您动态生成一个用户不友好的优惠券代码,这可能会不理想。 因此,可能需要更改此代码的显示方式。 为了实现这一点,存在过滤器 coupons。 此过滤器也可以用于显示或隐藏优惠券。 此过滤器不能用于更改优惠券的价值/总额。 这不会反映在购物车总额中。
参数
_coupons_object- 包含以下键的优惠券对象:_code_string- 优惠券代码。_discount_type_string- 折扣类型。 可以是percent或fixed_cart。_totals_object- 包含以下键的总额对象:_currency_code_string- 货币代码。_currency_decimal_separator_string- 货币小数分隔符。_currency_minor_unit_number- 货币最小单位。_currency_prefix_string- 货币前缀。_currency_suffix_string- 货币后缀。_currency_symbol_string- 货币符号。_currency_thousand_separator_string- 货币千位分隔符。_total_discount_string- 总折扣。_total_discount_tax_string- 总折扣税额。
_extensions_object(默认:{}) - 扩展对象。_args_object- 包含以下键的参数对象:_context_string(默认:summary) - 项目的上下文。
返回值
array- 包含与上述相同键的对象数组。
代码示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCoupons = ( coupons, extensions, args ) => {
return coupons.map( ( coupon ) => {
if ( ! coupon.label.match( /autocoupon(?:_\d+)+/ ) ) {
return coupon;
}
return {
...coupon,
label: 'Automatic coupon',
};
} );
};
registerCheckoutFilters( 'example-extension', {
coupons: modifyCoupons,
} );
过滤器也可以组合使用。 请参阅 组合过滤器 以获取示例。
截图
| 前面 | 后面 |
|---|---|
showApplyCouponNotice
描述
参数
- value
boolean(默认值:true) - 是否显示“应用优惠券”提示。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 参数对象,包含以下键:- context
string(允许的值:wc/cart和wc/checkout) - 优惠券提示的上下文。 - couponCode
string- 优惠券代码。
- context
返回值
boolean- 是否显示“应用优惠券”提示。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowApplyCouponNotice = ( defaultValue, extensions, args ) => {
return false;
};
registerCheckoutFilters( 'example-extension', {
showApplyCouponNotice: modifyShowApplyCouponNotice,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowApplyCouponNotice = ( defaultValue, extensions, args ) => {
if ( args?.couponCode === '10off' ) {
return false;
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
showApplyCouponNotice: modifyShowApplyCouponNotice,
} );
过滤器也可以组合使用。请参阅 组合过滤器 示例。
截图
| 前面 | 后面 |
|---|---|
showRemoveCouponNotice
描述
参数
_value_boolean(默认值:true) - 是否显示移除优惠券的提示。_extensions_object(默认值:{}) - 扩展对象。_args_object- 参数对象,包含以下键:_context_string(允许的值:wc/cart和wc/checkout) - 优惠券提示的上下文。_couponCode_string- 优惠券代码。
返回值
boolean- 是否显示移除优惠券的提示。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowRemoveCouponNotice = ( defaultValue, extensions, args ) => {
return false;
};
registerCheckoutFilters( 'example-extension', {
showRemoveCouponNotice: modifyShowRemoveCouponNotice,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyShowRemoveCouponNotice = ( defaultValue, extensions, args ) => {
if ( args?.couponCode === '10off' ) {
return false;
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
showRemoveCouponNotice: modifyShowRemoveCouponNotice,
} );
过滤器也可以组合使用。请参阅 组合过滤器 示例。
截图
| 前面 | 后面 |
|---|---|
订单摘要项目
以下订单摘要项目过滤器是可用的:
cartItemClasscartItemPricecartItemScreenReaderPriceitemNamesubtotalPriceFormat
以下对象在过滤器之间共享:
- 购物车对象
- 购物车项目对象
以下截图显示了各个过滤器影响的部分:

cartItemClass
描述
cartItemClass 过滤器允许修改订单摘要项目的类。
参数
- defaultValue
string(默认值:'') - 订单摘要项目的默认类。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:
返回值
string- 修改后的订单摘要项目类,或一个空字符串。
代码示例
基本示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemClass = ( defaultValue, extensions, args ) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
return 'my-custom-class';
};
registerCheckoutFilters( 'example-extension', {
cartItemClass: modifyCartItemClass,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemClass = ( defaultValue, extensions, args ) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return 'cool-class';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return 'hot-class';
}
return 'my-custom-class';
};
registerCheckoutFilters( 'example-extension', {
cartItemClass: modifyCartItemClass,
} );
过滤器也可以组合使用。请参阅 组合过滤器 以获取示例。
截图
| 之前 | 之后 |
|---|---|
cartItemPrice
描述
cartItemPrice 过滤器允许修改订单摘要项的价格格式。
参数
- defaultValue
string(默认值:<price/>) - 订单摘要项的默认价格。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 参数对象,包含以下键: - validation
boolean- 检查返回值是否包含子字符串<price/>。
返回值
string- 修改后的订单摘要项价格格式,必须包含子字符串<price/>,或者原始的价格格式。
代码示例
基本示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemPrice = ( defaultValue, extensions, args, validation ) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
return '<price/> for all items';
};
registerCheckoutFilters( 'example-extension', {
cartItemPrice: modifyCartItemPrice,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCartItemPrice = (defaultValue, extensions, args, validation) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return '<price/> to keep you ☀️';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return '<price/> to keep you ❄️';
}
return '<price/> for all items';
};
registerCheckoutFilters( 'example-extension', {
cartItemPrice: modifyCartItemPrice,
} );
过滤器也可以组合使用。请参阅 组合过滤器 了解示例。
截图
| 之前 | 之后 |
|---|---|
cartItemScreenReaderPrice
描述
cartItemScreenReaderPrice 过滤器允许格式化订单摘要中商品价格的朗读文本,以便屏幕阅读器和辅助技术用户能够听到。屏幕上不会有任何视觉上的变化。代码更改可以在购物车中每个项目的 <span class="screen-reader-text"> 标签中看到。
参数
- defaultValue
string(默认值:单个商品的总价为 <quantity/> <productName/>: <price/>;多个商品的总价为 <quantity/> <productName/>: <price/>) - 默认的订单摘要屏幕阅读器文本。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象: - validation
boolean- 检查返回值是否包含子字符串<quantity/>、<productName/>和<price/>。
返回值
string- 修改后的订单摘要项目价格格式,必须包含子字符串<quantity/>、<productName/>和<price/>。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const { _n } = window.wp.i18n;
const modifyCartItemScreenReaderPrice = ( defaultValue, extensions, args, validation ) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
return _n(
'<quantity/> <productName/> 项目的价格是 <price/>',
'<quantity/> <productName/> 项目的价格是 <price/>',
args?.cartItem?.quantity ?? 1,
'example-extension'
);
};
registerCheckoutFilters( 'example-extension', {
cartItemScreenReaderPrice: modifyCartItemScreenReaderPrice,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const { _n } = window.wp.i18n;
const modifyCartItemScreenReaderPrice = ( defaultValue, extensions, args, validation ) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return _n(
'总价为 <quantity/> <productName/> 项目: <price/>,让您保持温暖',
'总价为 <quantity/> <productName/> 项目: <price/>,让您保持温暖',
args?.cartItem?.quantity ?? 1,
'example-extension'
);
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return _n(
'总价为 <quantity/> <productName/> 项目: <price/>,让您保持凉爽',
'总价为 <quantity/> <productName/> 项目: <price/>,让您保持凉爽',
args?.cartItem?.quantity ?? 1,
'example-extension'
);
}
return defaultValue;
};
registerCheckoutFilters( 'example-extension', {
cartItemScreenReaderPrice: modifyCartItemScreenReaderPrice,
} );
过滤器也可以组合使用。请参阅 组合过滤器 示例。
itemName
描述
itemName 过滤器允许修改订单摘要项目名称。
参数
- defaultValue
string- 默认的订单摘要项目名称。 - extensions
object(默认:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:
返回值
string- 原始或修改后的订单摘要项目名称。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyItemName = (defaultValue, extensions, args) => {
const isOrderSummaryContext = args?.context === 'summary';
if (!isOrderSummaryContext) {
return defaultValue;
}
return `🪴 ${defaultValue} 🪴`;
};
registerCheckoutFilters('example-extension', {
itemName: modifyItemName,
});
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyItemName = (defaultValue, extensions, args) => {
const isOrderSummaryContext = args?.context === 'summary';
if (!isOrderSummaryContext) {
return defaultValue;
}
if (args?.cartItem?.name === 'Beanie with Logo') {
return `⛷️ ${defaultValue} ⛷️`;
}
if (args?.cartItem?.name === 'Sunglasses') {
return `🏄♂️ ${defaultValue} 🏄♂️`;
}
return `🪴 ${defaultValue} 🪴`;
};
registerCheckoutFilters('example-extension', {
itemName: modifyItemName,
});
过滤器也可以组合使用。请参阅 组合过滤器 了解示例。
截图
| Before | After |
|---|---|
subtotalPriceFormat
描述
subtotalPriceFormat 过滤器允许格式化订单摘要项的小计价格。
参数
- defaultValue
string(默认值:<price/>) - 订单摘要项的小计价格的默认值。 - extensions
object(默认值:{}) - 扩展对象。 - args
object- 包含以下键的参数对象: - validation
boolean- 检查返回值是否包含子字符串<price/>。
返回值
string- 修改后的订单摘要项小计价格的格式,必须包含子字符串<price/>,或者使用原始价格格式。
代码示例
基础示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySubtotalPriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
subtotalPriceFormat: modifySubtotalPriceFormat,
} );
高级示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifySubtotalPriceFormat = (
defaultValue,
extensions,
args,
validation
) => {
const isOrderSummaryContext = args?.context === 'summary';
if ( ! isOrderSummaryContext ) {
return defaultValue;
}
if ( args?.cartItem?.name === 'Beanie with Logo' ) {
return '<price/> per warm beanie';
}
if ( args?.cartItem?.name === 'Sunglasses' ) {
return '<price/> per cool sunglasses';
}
return '<price/> per item';
};
registerCheckoutFilters( 'example-extension', {
subtotalPriceFormat: modifySubtotalPriceFormat,
} );
过滤器也可以组合使用。请参阅 组合过滤器 示例。
截图
| Before | After |
|---|---|
购物车对象
上面筛选器的购物车对象具有以下关键字:
规则:
1. 翻译所有英文文本,包括标题、段落、列表项
2. 保持 Markdown 格式不变(#、**、``、[]() 等)
3. 代码块(```...```)内的代码不翻译,只翻译代码块外的文本
4. 保留所有占位符(%s, %d, {name})和 HTML 标签
5. 保留所有 URL 链接地址不翻译
6. 函数名、变量名、命令名保留英文原文
7. 只输出翻译结果,不要输出解释或原文
术语表(必须使用以下译法):
- String → 字符串
- Error → 错误
- Billing Address → 账单地址
- Currency Symbol → 货币符号
- Currency Code → 货币代码
- Total Price → 总价
- First name → 名
- Extensions → 扩展
- Last Name → 姓氏
- Discount → 折扣
- Currency → 货币
- Shipping → 配送
- Address → 地址
- Product → 产品
- Second → 秒
- Prefix → 前缀
- Suffix → 后缀
- number → 数值
- Coupon → 优惠券
- Rates → 费率
- _billingAddress_ `object` - 账单地址对象,包含以下键:
- _address_1_ `string` - 地址的第一行。
- _address_2_ `string` - 地址的第二行。
- _city_ `string` - 地址的城市。
- _company_ `string` - 地址的公司名称。
- _country_ `string` - 地址的国家。
- _email_ `string` - 地址的电子邮件。
- _first_name_ `string` - 地址的姓名。
- _last_name_ `string` - 地址的姓氏。
- _phone_ `string` - 地址的电话号码。
- _postcode_ `string` - 地址的邮政编码。
- _state_ `string` - 地址的省份/州。
- ~~_billingData_~~ `object` - 账单数据对象,包含与 `billingAddress` 对象相同的键。
- _cartCoupons_ `array` - 购物车优惠券数组。
- _cartErrors_ `array` - 购物车错误数组。
- _cartFees_ `array` - 购物车费用数组。
- _cartHasCalculatedShipping_ `boolean` - 是否已计算购物车运费。
- _cartIsLoading_ `boolean` - 购物车是否正在加载。
- _cartItemErrors_ `array` - 购物车商品错误数组。
- _cartItems_ `array` - 购物车商品数组,包含购物车商品对象,请参考 [购物车商品对象](#cart-item-object)。
- _cartItemsCount_ `number` - 购物车商品数量。
- _cartItemsWeight_ `number` - 购物车商品重量。
- _cartNeedsPayment_ `boolean` - 购物车是否需要支付。
- _cartNeedsShipping_ `boolean` - 购物车是否需要配送。
- _cartTotals_ `object` - 购物车总计对象,包含以下键:
- _currency_code_ `string` - 货币代码。
- _currency_decimal_separator_ `string` - 货币小数分隔符。
- _currency_minor_unit_ `number` - 货币最小单位。
- _currency_prefix_ `string` - 货币前缀。
- _currency_suffix_ `string` - 货币后缀。
- _currency_symbol_ `string` - 货币符号。
- _currency_thousand_separator_ `string` - 货币千位分隔符。
- _tax_lines_ `array` - 税收明细数组,包含税收明细对象,包含以下键:
- _name_ `string` - 税收明细名称。
- _price_ `number` - 税收明细价格。
- _rate_ `string` - 税收明细费率 ID。
- _total_discount_ `string` - 总折扣。
- _total_discount_tax_ `string` - 总折扣税额。
- _total_fees_ `string` - 总费用。
- _total_fees_tax_ `string` - 总费用税额。
- _total_items_ `string` - 总商品数量。
- _total_items_tax_ `string` - 总商品税额。
- _total_price_ `string` - 总价。
- _total_shipping_ `string` - 总运费。
- _total_shipping_tax_ `string` - 总运费税额。
- _total_tax_ `string` - 总税额。
- _crossSellsProducts_ `array` - 推荐商品数组,包含推荐商品对象。
- _extensions_ `object` (default: `{}`) - 扩展对象。
- _isLoadingRates_ `boolean` - 购物车是否正在加载配送费率。
- _paymentRequirements_ `array` - 支付要求数组。
- _shippingAddress_ `object` - 配送地址对象,包含与 `billingAddress` 对象相同的键。
- _shippingRates_ `array` - 配送费率数组。
购物车项目对象
上面筛选器中的购物车项目对象具有以下关键字:
项目详情
以下是项目详情的字段说明:
- backorders_allowed
boolean- 是否允许 延期交货。 - catalog_visibility
string- 目录可见性。 - decsription
string- 购物车项目描述。 - extensions
object(default:{}) - 扩展对象。 - id
number- 项目 ID。 - images
array- 项目 图像 数组。 - item_data
array- 项目数据数组。 - key
string- 项目键。 - low_stock_remaining
number- 剩余的低库存数量。 - name
string- 项目 名称。 - permalink
string- 项目 固定链接。 - prices
object- 项目价格对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - price
string- 价格。 - price_range
string- 价格范围。 - raw_prices
object- 原始价格对象,包含以下键:- precision
number- 精度。 - price
number- 价格。 - regular_price
number- 常规价格。 - sale_price
number- 促销价格。
- precision
- regular_price
string- 常规价格。 - sale_price
string- 促销价格。
- currency_code
- quantity
number- 项目 数量。 - quantity_limits
object- 项目数量限制对象,包含以下键:- editable
boolean- 是否可编辑数量。 - maximum
number- 最大数量。 - minimum
number- 最小数量。 - multiple_of
number- 数量的倍数。
- editable
- short_description
string- 项目简短描述。 - show_backorder_badge
boolean- 是否显示 延期交货 徽章。 - sku
string- 项目 SKU。 - sold_individually
boolean- 是否单独销售项目。 - totals
object- 项目总计对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - line_subtotal
string- 行 小计。 - line_subtotal_tax
string- 行 小计 税。 - line_total
string- 行总计。 - line_total_tax
string- 行总计税。
- currency_code
- type
string- 项目类型。 - variation
array- 项目 变体 数组。
Totals footer item
totalLabeltotalValue
totalLabel
以下对象用于过滤器:
Description
totalLabel 过滤器允许修改购物车和结账模块底部总价项的标签。
Parameters
- defaultValue
string(default:Total) - 总价标签。 - extensions
object(default:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅 Cart object。
- cart
Returns
string- 修改后的总价标签。
代码示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyTotalLabel = ( defaultValue, extensions, args ) => {
return 'Deposit due today';
};
registerCheckoutFilters( 'example-extension', {
totalLabel: modifyTotalLabel,
} );
过滤器可以组合使用。请参阅 Combined filters 以获取示例。
截图
| Before | After |
|---|---|
totalValue
以下对象用于过滤器:
Description
totalValue 过滤器允许格式化购物车和结账模块底部总价。
Parameters
- defaultValue
string(default:Total) - 总价标签。 - extensions
object(default:{}) - 扩展对象。 - args
object- 包含以下键的参数对象:- cart
object- 来自wc/store/cart的购物车对象,请参阅 Cart object。
- cart
- validation
boolean- 检查返回值是否包含子字符串<price/>。
Returns
string- 修改后的总价格式,必须包含子字符串<price/>,或者原始的总价格式。
代码示例
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyTotalsPrice = ( defaultValue, extensions, args, validation ) => {
return 'Pay <price/> now';
};
registerCheckoutFilters( 'my-extension', {
totalValue: modifyTotalsPrice,
} );
过滤器可以组合使用。请参阅 Combined filters 以获取示例。
截图
| 前 | 后 |
|---|---|
购物车对象
上面筛选器的购物车对象具有以下关键字:
规则:
1. 翻译所有英文文本,包括标题、段落、列表项
2. 保持 Markdown 格式不变(#、**、``、[]() 等)
3. 代码块(```...```)内的代码不翻译,只翻译代码块外的文本
4. 保留所有占位符(%s, %d, {name})和 HTML 标签
5. 保留所有 URL 链接地址不翻译
6. 函数名、变量名、命令名保留英文原文
7. 只输出翻译结果,不要输出解释或原文
术语表(必须使用以下译法):
- String → 字符串
- Error → 错误
- Billing Address → 账单地址
- Currency Symbol → 货币符号
- Currency Code → 货币代码
- Total Price → 总价
- First name → 名
- Extensions → 扩展
- Last Name → 姓氏
- Discount → 折扣
- Currency → 货币
- Shipping → 配送
- Address → 地址
- Product → 产品
- Second → 秒
- Prefix → 前缀
- Suffix → 后缀
- number → 数值
- Coupon → 优惠券
- Rates → 费率
- _billingAddress_ `object` - 账单地址对象,包含以下键:
- _address_1_ `string` - 地址的第一行。
- _address_2_ `string` - 地址的第二行。
- _city_ `string` - 地址的城市。
- _company_ `string` - 地址的公司名称。
- _country_ `string` - 地址的国家。
- _email_ `string` - 地址的电子邮件。
- _first_name_ `string` - 地址的姓名。
- _last_name_ `string` - 地址的姓氏。
- _phone_ `string` - 地址的电话号码。
- _postcode_ `string` - 地址的邮政编码。
- _state_ `string` - 地址的省份/州。
- ~~_billingData_~~ `object` - 账单数据对象,包含与 `billingAddress` 对象相同的键。
- _cartCoupons_ `array` - 购物车优惠券数组。
- _cartErrors_ `array` - 购物车错误数组。
- _cartFees_ `array` - 购物车费用数组。
- _cartHasCalculatedShipping_ `boolean` - 是否已计算购物车运费。
- _cartIsLoading_ `boolean` - 购物车是否正在加载。
- _cartItemErrors_ `array` - 购物车商品错误数组。
- _cartItems_ `array` - 购物车商品数组,包含购物车商品对象,请参考 [购物车商品对象](#cart-item-object)。
- _cartItemsCount_ `number` - 购物车商品数量。
- _cartItemsWeight_ `number` - 购物车商品重量。
- _cartNeedsPayment_ `boolean` - 购物车是否需要支付。
- _cartNeedsShipping_ `boolean` - 购物车是否需要配送。
- _cartTotals_ `object` - 购物车总计对象,包含以下键:
- _currency_code_ `string` - 货币代码。
- _currency_decimal_separator_ `string` - 货币小数分隔符。
- _currency_minor_unit_ `number` - 货币最小单位。
- _currency_prefix_ `string` - 货币前缀。
- _currency_suffix_ `string` - 货币后缀。
- _currency_symbol_ `string` - 货币符号。
- _currency_thousand_separator_ `string` - 货币千位分隔符。
- _tax_lines_ `array` - 税收明细数组,包含税收明细对象,包含以下键:
- _name_ `string` - 税收明细名称。
- _price_ `number` - 税收明细价格。
- _rate_ `string` - 税收明细费率 ID。
- _total_discount_ `string` - 总折扣。
- _total_discount_tax_ `string` - 总折扣税额。
- _total_fees_ `string` - 总费用。
- _total_fees_tax_ `string` - 总费用税额。
- _total_items_ `string` - 总商品数量。
- _total_items_tax_ `string` - 总商品税额。
- _total_price_ `string` - 总价。
- _total_shipping_ `string` - 总运费。
- _total_shipping_tax_ `string` - 总运费税额。
- _total_tax_ `string` - 总税额。
- _crossSellsProducts_ `array` - 推荐商品数组,包含推荐商品对象。
- _extensions_ `object` (default: `{}`) - 扩展对象。
- _isLoadingRates_ `boolean` - 购物车是否正在加载配送费率。
- _paymentRequirements_ `array` - 支付要求数组。
- _shippingAddress_ `object` - 配送地址对象,包含与 `billingAddress` 对象相同的键。
- _shippingRates_ `array` - 配送费率数组。
购物车项目对象
上面筛选器中的购物车项目对象具有以下关键字:
项目详情
以下是项目详情的字段说明:
- backorders_allowed
boolean- 是否允许 延期交货。 - catalog_visibility
string- 目录可见性。 - decsription
string- 购物车项目描述。 - extensions
object(default:{}) - 扩展对象。 - id
number- 项目 ID。 - images
array- 项目 图像 数组。 - item_data
array- 项目数据数组。 - key
string- 项目键。 - low_stock_remaining
number- 剩余的低库存数量。 - name
string- 项目 名称。 - permalink
string- 项目 固定链接。 - prices
object- 项目价格对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - price
string- 价格。 - price_range
string- 价格范围。 - raw_prices
object- 原始价格对象,包含以下键:- precision
number- 精度。 - price
number- 价格。 - regular_price
number- 常规价格。 - sale_price
number- 促销价格。
- precision
- regular_price
string- 常规价格。 - sale_price
string- 促销价格。
- currency_code
- quantity
number- 项目 数量。 - quantity_limits
object- 项目数量限制对象,包含以下键:- editable
boolean- 是否可编辑数量。 - maximum
number- 最大数量。 - minimum
number- 最小数量。 - multiple_of
number- 数量的倍数。
- editable
- short_description
string- 项目简短描述。 - show_backorder_badge
boolean- 是否显示 延期交货 徽章。 - sku
string- 项目 SKU。 - sold_individually
boolean- 是否单独销售项目。 - totals
object- 项目总计对象,包含以下键:- currency_code
string- 货币代码。 - currency_decimal_separator
string- 货币小数分隔符。 - currency_minor_unit
number- 货币最小单位。 - currency_prefix
string- 货币前缀。 - currency_suffix
string- 货币后缀。 - currency_symbol
string- 货币符号。 - currency_thousand_separator
string- 货币千位分隔符。 - line_subtotal
string- 行 小计。 - line_subtotal_tax
string- 行 小计 税。 - line_total
string- 行总计。 - line_total_tax
string- 行总计税。
- currency_code
- type
string- 项目类型。 - variation
array- 项目 变体 数组。
产品集合块发出的 DOM 事件
wc-blocks_product_list_rendered
当产品集合块被渲染或重新渲染时(例如,由于网页更改),会触发此事件。
detail 参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
collection |
字符串 | undefined |
集合类型。对于“创建自己的”集合,由于类型未指定,其值为 undefined。对于其他核心集合,它可以是以下类型之一:woocommerce/product-collection/best-sellers、woocommerce/product-collection/featured、woocommerce/product-collection/new-arrivals、woocommerce/product-collection/on-sale、woocommerce/product-collection/top-rated。对于自定义集合,它将包含其名称。 |
示例用法
window.document.addEventListener(
'wc-blocks_product_list_rendered',
( e ) => {
const { collection } = e.detail;
console.log( collection ) // -> 集合名称,例如:woocommerce/product-collection/on-sale
}
);
事件: wc-blocks_viewed_product
当某些块被点击以查看产品(重定向到产品网页)时,会触发此事件。
detail 参数
| 参数 | 类型: | 默认值 | 描述 |
|---|---|---|---|
collection |
字符串 | undefined |
集合类型。对于“自定义”集合,类型未定义。对于其他核心集合,它可以是以下类型之一:woocommerce/product-collection/best-sellers、woocommerce/product-collection/featured、woocommerce/product-collection/new-arrivals、woocommerce/product-collection/on-sale、woocommerce/product-collection/top-rated。对于自定义集合,它将包含其名称。 |
productId |
数值 | 产品 ID |
用法示例
window.document.addEventListener(
'wc-blocks_viewed_product',
( e ) => {
const { collection, productId } = e.detail;
console.log( collection ) // -> 集合名称,例如 "woocommerce/product-collection/featured" 或对于默认集合,值为 undefined
console.log( productId ) // -> 产品 ID,例如 34
}
);
在产品集合块中注册自定义集合
__experimentalRegisterProductCollection 函数是 @woocommerce/blocks-registry 包的一部分。 此函数允许第三方开发者注册一个新的集合。 此函数接受大多数 [Block Variation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/#defining-a-block-variation) 接受的参数。
注意: 这是一个实验性功能,未来可能会发生变化。 请谨慎使用。
有两种使用此函数的方法:
-
在 Webpack 配置中使用
@woocommerce/dependency-extraction-webpack-plugin: 这将允许您从包中导入该函数并在您的代码中使用它。 例如:import { __experimentalRegisterProductCollection } from "@woocommerce/blocks-registry"; -
使用全局
wc对象: 这将允许您使用全局 JavaScript 对象来使用该函数,而无需导入它。 例如:wc.wcBlocksRegistry.__experimentalRegisterProductCollection({ ... });
如果您选择使用全局 wc,请确保将 wc-blocks-registry 添加为您的脚本的依赖项。
function enqueue_my_custom_product_collection_script() {
wp_enqueue_script(
'my-custom-product-collection',
plugins_url( '/dist/my-custom-product-collection.js', __FILE__ ),
array( 'wc-blocks-registry' ),
10
);
}
add_action( 'enqueue_block_editor_assets', 'enqueue_my_custom_product_collection_script' );
提示: 如果您正在使用 Webpack,建议使用第一种方法。
定义集合
我们将解释可以传递给 __experimentalRegisterProductCollection 的重要参数。对于其他参数,您可以参考 Block Variation 文档。
集合由一个对象定义,该对象可以包含以下字段:
name(类型string): 一个唯一且可供机器读取的集合名称。我们建议使用<plugin-name>/product-collection/<collection-name>的格式。<plugin-name>和<collection-name>应该只包含字母数字字符和连字符 (例如:my-plugin/product-collection/my-collection)。title(类型string): 集合的标题,将在各种地方显示,包括块插入器和集合选择器。description(可选,类型string): 集合的易于理解的描述。innerBlocks(可选,类型Array[]): 将添加到集合中的内部块数组。如果未提供,将使用默认的内部块。isDefault: 对于所有集合,该值设置为false。第三方开发者无需传递此参数。isActive: 将由我们管理。第三方开发者无需传递此参数。usesReference(可选,类型Array[]): 一个字符串数组,指定集合所需的引用。可接受的值包括product、archive、cart和order。当编辑器端不可用但前端可用的引用时,我们将显示一个预览标签。scope(可选,类型Array[]): 集合适用的范围列表。可接受的值包括block、inserter和transform。默认为["block", "inserter"]。- 注意: 对于产品集合块,
block范围意味着该集合将在集合选择器中显示,并且“选择集合”工具栏按钮将可见。对于其他范围,您可以参考 Block Variation 文档。
- 注意: 对于产品集合块,
属性
属性是定义集合行为的特性。所有属性都是可选的。以下是一些可以传递给 __experimentalRegisterProductCollection 的重要属性:
-
query(类型object): 定义集合查询的对象。它可以包含以下字段:offset(类型number): 用于偏移查询的项目数量。order(类型string): 查询的排序方式。 接受的值为asc和desc。orderBy(类型string): 用于排序的字段。pages(类型number): 要查询的页数。perPage(类型number): 每页的产品数量。search(类型string): 用于查询的搜索词。taxQuery(类型object): 用于过滤查询的分类查询。例如,如果您想要获取分类为Clothing和Accessories且标签为Summer的产品,则可以将taxQuery设置为{"product_cat":[20,17],"product_tag":[36]}。其中数组值是术语 ID。featured(类型boolean): 是否查询精选商品。timeFrame(类型object): 用于查询的时间范围。operator(类型string): 用于时间范围查询的操作符。 接受的值为in和not-in。value(类型string): 用于查询的值。 应该是一个有效的日期字符串,PHP 的strtotime函数可以解析。
woocommerceOnSale(类型boolean): 是否查询促销商品。woocommerceStockStatus(类型array): 用于查询的库存状态。 接受的值包括instock、outofstock和onbackorder。woocommerceAttributes(类型array): 用于查询的属性。- 例如,如果您想要获取颜色为
blue和gray且尺寸为Large的产品,则可以将woocommerceAttributes设置为[{"termId":23,"taxonomy":"pa_color"},{"termId":26,"taxonomy":"pa_size"},{"termId":29,"taxonomy":"pa_color"}]。
- 例如,如果您想要获取颜色为
woocommerceHandPickedProducts(类型array): 用于查询的手选产品。 应该包含产品 ID。priceRange(类型object): 用于查询的价格范围。min(类型number): 最小价格。max(类型number): 最大价格。
-
displayLayout(类型object): 定义集合布局的布局对象。它可以包含以下字段:type(类型string): 布局类型。 接受的值为grid、stack和carousel。columns(类型number): 要显示的列数。shrinkColumns(类型boolean): 是否使布局具有响应式。
产品管理
本页面用于管理产品信息。
产品列表
产品列表显示所有已创建的产品。您可以根据不同的条件进行筛选和排序。
- 分类 (Category): 产品所属的分类。
- 产品标签 (Product Tags): 与产品相关的标签。
- 状态 (Status): 产品的当前状态。
- 产品属性 (Product Attributes): 产品的各种属性。
- 库存状态 (Stock Status): 产品的库存状态。
您可以通过以下方式进行筛选:
- 创建时间 (Created): 按创建时间排序。
- 精选 (Featured): 显示或隐藏精选产品。
- 手工挑选 (Hand-picked): 显示或隐藏手工挑选的产品。
- 关键字 (Key): 根据关键字搜索产品。
- 促销 (On Sale): 显示或隐藏促销产品。
- 库存状态 (Stock Status): 根据库存状态筛选产品。
- 分类法 (Taxonomy): 筛选产品分类、产品标签和自定义分类法。
- 价格范围 (Price Range): 根据价格范围筛选产品。
您还可以通过以下方式进行排序:
- 排序方式 (Order): 按不同的字段进行排序。
产品详情
产品详情页面显示单个产品的详细信息。
- 产品 (Product): 产品的名称和描述。
- 产品属性 (Product Attributes): 产品的各种属性。
- 产品标签 (Product Tags): 与产品相关的标签。
- 库存 (Stock): 产品的库存数量。
- 价格 (Value): 产品的价格。
- 订单 (Order): 与该产品相关的订单信息。
产品设置
产品设置页面允许您配置产品的各种设置。
-
隐藏控件 (Hide Controls): 可以隐藏以下控件:
hideControls(类型array): 要隐藏的控件。 可能的值:order- "排序方式" 设置attributes- "产品属性" 过滤器created- "创建时间" 过滤器featured- "精选" 过滤器hand-picked- "手工挑选的产品" 过滤器keyword- "关键字" 过滤器on-sale- "促销" 过滤器stock-status- "库存状态" 过滤器taxonomy- "产品分类"、"产品标签" 和自定义分类法 过滤器price-range- "价格范围" 过滤器
-
其他设置: 您可以设置产品的其他属性,例如颜色 (Red) 和其他参数。
创建产品
您可以在此页面创建新的产品。 填写必要的信息,然后点击 "创建" 按钮。 确保填写所有必填字段。
范围 (Range)
产品属性的范围可以定义为最小值和最大值。
标签 (Tag)
每个产品可以拥有多个标签,用于方便搜索和分类。
设置 (Setting)
系统设置允许您配置各种全局参数。
Preview 属性
preview 属性是可选的,用于设置集合的预览状态。它可以包含以下字段:
initialPreviewState(类型object): 集合的初始预览状态。它可以包含以下字段:isPreview(类型boolean): 是否处于查看模式。previewMessage(类型string): 当用户将鼠标悬停在预览标签上时,在工具提示中显示的提示信息。
setPreviewState(可选,类型function): 用于设置集合的预览状态的函数。它接收以下参数:setState(类型function): 用于设置预览状态的函数。您可以向此函数传递一个新的预览状态,其中包含isPreview和previewMessage。attributes(类型object): 集合的当前属性。location(类型object): 集合的位置。 接受的值包括product、archive、cart、order、site。
有关更多信息,您可以查看 PR #46369,其中添加了预览功能。
示例
示例 1:注册一个新的集合
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection",
title: "My Custom Collection",
icon: "games",
description: "This is a custom collection.",
keywords: ["custom collection", "product collection"],
});
如上例所示,我们正在注册一个名为 woocommerce/product-collection/my-custom-collection 且标题为 My Custom Collection 的新集合。以下是其外观的截图:
示例 2:注册一个带有预览的新集合
如以下所示,设置初始预览状态是可能的。 在以下示例中,我们设置 isPreview 和 previewMessage。
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection-with-preview",
title: "My Custom Collection with Preview",
icon: "games",
description: "This is a custom collection with preview.",
keywords: ["My Custom Collection with Preview", "product collection"],
preview: {
initialPreviewState: {
isPreview: true,
previewMessage:
"This is a preview message for my custom collection with preview.",
},
},
attributes: {
query: {
perPage: 5,
featured: true,
},
displayLayout: {
type: "grid",
columns: 3,
shrinkColumns: true,
},
hideControls: [ "created", "stock-status" ]
},
});
以下是其外观的截图:
示例 3:高级预览用法
如您在下面看到的,也可以使用 setPreviewState 来设置预览状态。在下面的示例中,我们设置了 initialPreviewState,并使用 setPreviewState 在 5 秒后更改预览状态。
此示例展示:
- 如何访问预览状态中的当前属性和位置
- 如何使用异步操作
- 我们使用
setTimeout在 5 秒后更改预览状态。您可以根据需要使用任何异步操作,例如从 API 获取数据,以确定预览状态。
- 我们使用
- 如何将清理函数作为返回值使用
- 我们返回一个清理函数,该函数将在组件卸载后清除超时。您可以使用此函数来清理在
setPreviewState中使用的任何资源。
- 我们返回一个清理函数,该函数将在组件卸载后清除超时。您可以使用此函数来清理在
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection-with-advanced-preview",
title: "My Custom Collection with Advanced Preview",
icon: "games",
description: "This is a custom collection with advanced preview.",
keywords: [
"My Custom Collection with Advanced Preview",
"product collection",
],
preview: {
setPreviewState: ({
setState,
attributes: currentAttributes,
location,
}) => {
// setPreviewState 可以访问当前的属性和位置。
// console.log( currentAttributes, location );
const timeoutID = setTimeout(() => {
setState({
isPreview: false,
previewMessage: "",
});
}, 5000);
return () => clearTimeout(timeoutID);
},
initialPreviewState: {
isPreview: true,
previewMessage:
"This is a preview message for my custom collection with advanced preview.",
},
},
});
示例 4:带有内部块的集合
如您在下面看到的,也可以为集合定义内部块。在下面的示例中,我们正在为集合定义内部块。
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection-with-inner-blocks",
title: "My Custom Collection with Inner Blocks",
icon: "games",
description: "This is a custom collection with inner blocks.",
keywords: ["My Custom Collection with Inner Blocks", "product collection"],
innerBlocks: [
[
"core/heading",
{
textAlign: "center",
level: 2,
content: "Title of the collection",
},
],
[
"woocommerce/product-template",
{},
[
["woocommerce/product-image"],
[
"woocommerce/product-price",
{
textAlign: "center",
fontSize: "small",
},
],
],
],
],
});
这将创建一个包含标题、产品图像和产品价格的集合。它看起来如下所示:
提示: 您可以在 Inner Blocks 文档中了解有关内部块模板的更多信息。
示例 5:带有 usesReference 参数的集合
当集合需要引用才能正常工作时,可以使用 usesReference 参数来指定它。在下面的示例中,我们正在定义一个需要 product 引用的集合。
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection",
title: "My Custom Collection",
icon: "games",
description: "This is a custom collection.",
keywords: ["custom collection", "product collection"],
usesReference: ["product"],
});
这将创建一个需要 product 引用的集合。如果编辑器端不可用,但在前端可用的必需引用,我们将显示一个预览标签。
当集合需要多个引用之一时,可以使用 usesReference 参数来指定它。在下面的示例中,我们正在定义一个需要 product 或 order 引用的集合。
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection",
title: "My Custom Collection",
icon: "games",
description: "This is a custom collection.",
keywords: ["custom collection", "product collection"],
usesReference: ["product", "order"],
});
示例 6:scope 参数
当您不指定 scope 参数时,其默认值是 ["block", "inserter"]。 这种默认行为是从 Block Variation API 继承而来的。
Product Collection 块使用 block 范围来控制:
- 在集合选择器中的可见性
- "选择集合" 工具栏按钮的显示
不在集合选择器中显示集合
如果您不想在集合选择器中显示您的集合,可以将 scope 参数设置为一个空数组或任何不包含 block 值的其他值。
例如:
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection",
title: "My Custom Collection",
icon: "games",
description: "This is a custom collection.",
keywords: ["custom collection", "product collection"],
scope: [],
});
仅在块插入器中显示集合
如果您希望仅在块插入器中显示您的集合,而不在集合选择器中显示,可以将 scope 参数设置为 ["inserter"]。 这允许用户直接从块插入器添加您的自定义集合,同时将其隐藏在集合选择器界面中。
例如:
__experimentalRegisterProductCollection({
name: "your-plugin-name/product-collection/my-custom-collection",
title: "My Custom Collection",
description: "This is a custom collection.",
keywords: ["custom collection", "product collection"],
scope: ["inserter"],
});
块中的可扩展性
这些文档都涉及 WooCommerce 各种块中的可扩展性。
导入和依赖项提取
本部分的文档在代码示例中会使用 window 全局变量,例如:
const { registerCheckoutFilters } = window.wc.blocksCheckout;
但是,如果您正在使用 @woocommerce/dependency-extraction-webpack-plugin 以获得更高级别的依赖项管理,则可以使用 ES 模块语法:
import { registerCheckoutFilters } from '@woocommerce/blocks-checkout';
有关更多信息,请参阅 @woocommerce/dependency-extraction-webpack-plugin。
钩子 (操作和过滤器)
| 文档 | 描述 |
|---|---|
| 操作 | 涵盖服务器端操作钩子的文档。 |
| 过滤器 | 涵盖服务器端过滤器钩子的文档。 |
| 迁移的钩子 | 涵盖已迁移的 WooCommerce 核心钩子的文档。 |
REST API
| 文档 | 描述 |
|---|---|
| 在 Store API 中暴露您的数据。 | 解释了如何向 Store API 端点添加额外的数据。 |
| 可用于扩展的端点列表 | 包含所有可用于扩展的端点列表。 |
| 可用的格式化器 | 可用的 Formatters,用于格式化 Store API 中使用的数据。 |
| 使用 Store API 更新购物车 | 在前端执行操作后,更新服务器端的购物车。 |
结账 付款方式
| 文档 | 描述 |
|---|---|
| 结账流程和事件 | 关于结账块中的结账流程以及可以订阅的各种事件的信息。 |
| 付款方式集成 | 关于实现付款方式的信息。 |
| 过滤付款方式 | 关于过滤结账块中可用付款方式的信息。 |
结账模块
除了以下参考资料,请参阅 block-checkout 软件包的文档,该文档用于通过 Filters、Slot Fills 和 Inner Blocks 来扩展结账功能。
| 文档 | 描述 |
|---|---|
| 如何使用结账模块处理订单 | 详细介绍结账流程的内部机制。 |
| IntegrationInterface | IntegrationInterface 类及其用法,用于向 WooCommerce Blocks 注册脚本、样式和数据。 |
| 可用的 Filters | 关于可以使用的 Filters,用于修改 WooCommerce Blocks 中某些元素的数值。 |
| Slots and Fills | 解释 Slot Fills 及其用法,用于在购物车和结账页面渲染您自己的组件。 |
| 可用的 Slot Fills | 可以使用的 Slots 及其在购物车和结账页面上的位置。 |
| DOM Events | 一些模块使用的 DOM Events 列表,用于在模块之间以及与 WooCommerce 的其他部分进行通信。 |
| Filter Registry | Filter Registry 允许注册回调函数,以修改某些值。 |
| 额外的结账字段 | Filter Registry 允许注册回调函数,以修改某些值。 |
常见问题
本文档旨在解答一些来自扩展 WooCommerce Blocks 的开发者的常见问题。
我们会根据收到的问题不断更新此 FAQ 文档,这并非文档的最终版本。
如果您有此处未提及的问题,我们邀请您在 GitHub 讨论 或 WooCommerce 社区 Slack 上提出。
常见问题
如何响应购物车或结账的更改,例如配送方式选择或地址更改?
购物车和结账模块从 @wordpress/data 数据存储 读取所有数据。我们还提供了 WooCommerce Blocks 使用的数据存储的文档。
开发者通常希望响应购物车或结账中的更改。例如,当用户更改他们的配送方式或修改地址中的某一项时。
根据您的代码运行方式,有两种实现方法。
如果您的代码在 React 组件中运行
如果您的组件是购物车/结账模块的内部块,或者在 Slot/Fill 中渲染,您可以直接从相关的数据存储中选择所需的数据,并在数据发生变化时执行必要的操作。有关可用选择器的更多信息,请参阅 相关数据存储的文档。
/**
* 外部依赖
*/
import { useSelect } from '@wordpress/data';
import { cartStore } from '@woocommerce/block-data';
import { useEffect } from '@wordpress/element';
export const MyComponent = () => {
const { shippingAddress } = useSelect(
( select ) => select( cartStore ).getCartData(),
[]
);
useEffect( () => {
// 当 shippingAddress 发生变化时,执行某些操作
}, [ shippingAddress ] );
};
如果您的代码运行在非 React 环境中
如果您的代码没有进行任何 阻止 的 渲染,或者没有运行任何 React 代码,那么上述情况就成立。这意味着您将无法 访问 React 钩子 或自定义 钩子,例如 useSelect。 在这种情况下,您需要使用 useSelect 的非 钩子 替代方案,即 select。 考虑到需要响应变化,仅仅调用 select 是不够的,因为它只会运行一次。 您需要使用 subscribe 方法 来 订阅 您感兴趣的数据的变化。
/**
* 外部依赖
*/
import { select, subscribe } from '@wordpress/data';
import { cartStore } from '@woocommerce/block-data';
let previousCountry = '';
const unsubscribe = subscribe( () => {
const { shippingAddress } = select( cartStore ).getCartData();
if ( shippingAddress.country !== previousCountry ) {
previousCountry = shippingAddress.country;
// 当 `配送` 国家发生变化时,执行某些操作。
}
if ( /* 某些其他 `条件`,使得此 `订阅` 不再需要 */ ) {
unsubscribe();
}
}, cartStore );
由于 subscribe 回调函数会在数据 商店 接收到任何操作时运行,因此您需要使用 缓存 来避免在不需要时执行操作。 例如,如果您只想在国家发生变化时执行操作,则需要 缓存 之前的 价值,并在执行任务之前将其与 当前 价值 进行比较。
如果不再需要响应变化,您可以使用 unsubscribe 方法 从数据 商店 取消 订阅,该 方法 由 subscribe 方法 返回,如上面的示例所示。
购物车修改
如何从客户端动态地修改购物车内容?
要基于客户端操作在服务器上执行操作,您需要使用 extensionCartUpdate。
例如,要在您的网站上添加一个“如果您注册邮件列表,即可获得 10% 的折扣”的复选框,您可以使用 extensionCartUpdate 自动将 10% 的优惠券应用于购物车。
假设您已经添加了复选框,可以通过“附加结账字段 API”或创建内部块来实现,下一步是注册服务器端代码,以便在选中复选框时应用优惠券,反之则移除优惠券。
add_action('woocommerce_blocks_loaded', function() {
woocommerce_store_api_register_update_callback(
[
'namespace' => 'extension-unique-namespace',
'callback' => function( $data ) {
if ( isset( $data['checked'] ) && filter_var( $data['checked'], FILTER_VALIDATE_BOOLEAN ) === true ) {
WC()->cart->apply_coupon( 'mailing-list-10-percent-coupon' );
} else {
WC()->cart->remove_coupon( 'mailing-list-10-percent-coupon' );
}
}
]
);
} );
复选框的前端事件监听器代码如下所示:
const { extensionCartUpdate } = window.wc.blocksCheckout;
const onChange = ( checked ) => {
extensionCartUpdate(
{
namespace: 'extension-unique-namespace',
data: {
checked
}
}
)
}
要更改如何在订单摘要中的优惠券列表中显示此优惠券,可以使用 coupons 结账过滤器,如下所示:
const { registerCheckoutFilters } = window.wc.blocksCheckout;
const modifyCoupons = ( coupons, extensions, args ) => {
return coupons.map( ( coupon ) => {
if ( ! coupon.label === 'mailing-list-10-percent-coupon' ) {
return coupon;
}
return {
...coupon,
label: 'Mailing list discount',
};
} );
};
registerCheckoutFilters( 'extension-unique-namespace', {
coupons: modifyCoupons,
} );
如何在选择特定支付方式时,向购物车添加费用?
您需要在服务器端,根据所选的支付方式添加费用。这可以通过使用 woocommerce_cart_calculate_fees 动作来实现。
以下是用于添加费用的服务器端代码:
add_action(
'woocommerce_cart_calculate_fees',
function () {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
$chosen_payment_method_id = WC()->session->get( 'chosen_payment_method' );
$cart = WC()->cart;
if ( 'your-payment-method-slug' === $chosen_payment_method_id ) {
$percentage = 0.05;
$surcharge = ( $cart->cart_contents_total + $cart->shipping_total ) * $percentage;
$cart->add_fee( 'Payment method fee', $surcharge );
}
}
);
如何从服务器强制刷新购物车?
这可以通过使用 extensionCartUpdate 来实现,这是推荐的方法。 另一种方法是通过在有效的购物车对象上执行 wc/store/cart 数据存储中的 receiveCart 动作,如下所示:
const { dispatch } = window.wp.data;
dispatch( 'wc/store/cart' ).receiveCart( cartObject )
Store API 上的所有购物车路由都会返回一个购物车对象,可以用于此操作。 传递无效的购物车对象会导致块中出现错误。
您也可以使用:
const { dispatch } = window.wp.data;
dispatch('wc/store/cart').invalidateResolutionForStore()
但是,这会导致在获取新购物车时,短暂地显示一个空购物车。
如何在每个购物车项中渲染内容?
目前,这不是官方支持的功能。 但是,我们听说一些开发者通过使用 DOM 操作和 React portals 来实现这一点。 如果您选择采用此方法,请注意,如果我们在未来对购物车块进行更改,您的集成可能会停止工作。
结账修改
如何移除结账字段?
我们不建议这样做,因为 WordPress 和 Woo 支持大量的插件。 其中一些插件可能依赖于某些结账字段才能正常工作。 但是,如果您确定这些字段可以安全移除,请参阅 移除结账字段。
如何在结账过程中修改订单或客户数据?
如果您想修改在结账过程中提交的订单或客户数据,可以使用 woocommerce_store_api_checkout_order_processed 动作。
此动作在支付处理之前触发。 在此时,您可以像在 WooCommerce 生命周期中的任何其他时间一样修改订单,但您仍然需要调用 $order->save() 以保存更改。
例如,让我们确保用户的姓氏和名首字母大写:
add_action(
'woocommerce_store_api_checkout_order_processed',
function( WC_Order $order ) {
$order->set_shipping_first_name( ucfirst( $order->get_shipping_first_name() ) );
$order->set_shipping_last_name( ucfirst( $order->get_shipping_last_name() ) );
$order->set_billing_first_name( ucfirst( $order->get_billing_first_name() ) );
$order->set_billing_last_name( ucfirst( $order->get_billing_last_name() ) );
$order->save();
}
);
如何在结账块中渲染内容?
这取决于您想要渲染的内容。
渲染字段
在结账块中渲染字段的推荐方法是使用 额外的结账字段 API。
渲染自定义块
要在结账块中渲染自定义块,推荐的方法是创建一个现有结账内部块的子块。 我们有一个示例模板,可用于设置和研究内部块。 要安装和使用它,请按照 @woocommerce/extend-cart-checkout-block 中的说明进行操作。 请注意,此示例包含其他可扩展性的多个示例,而不仅仅是内部块。
Blocks 参考
本页面列出了该包中包含的 Woo 组件。 (由于仍有一些组件尚未采用 block.json 定义,因此此列表可能不完整)。
产品平均评分 (Beta) - woocommerce/product-average-rating
显示产品的平均评分。
- Name: woocommerce/product-average-rating
- Category: woocommerce-product-elements
- Ancestor: woocommerce/single-product
- Parent:
- Supports: color (背景, 文本), interactivity (clientNavigation), spacing (间距, padding), typography (fontSize)
- Attributes: textAlign
加入购物车 按钮 - woocommerce/product-button
显示一个行动按钮,该按钮可以将产品添加到购物车,或者链接到产品页面。
- Name: woocommerce/product-button
- Category: woocommerce-product-elements
- Ancestor: woocommerce/all-products, woocommerce/single-product, core/post-template, woocommerce/product-template
- Parent:
- Supports: align (full, wide), color (背景, 文本,
链接), email, interactivity, spacing (间距, padding), typography (fontSize, lineHeight),html - Attributes: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, productId, textAlign, width
产品 图像 - woocommerce/product-image
显示主要的产品图像。
- Name: woocommerce/product-image
- Category: woocommerce-product-elements
- Ancestor: woocommerce/all-products, woocommerce/single-product, woocommerce/product-template, core/post-template
- Parent:
- Supports: dimensions (aspectRatio), email, interactivity (clientNavigation), spacing (间距, padding), typography (fontSize),
html - Attributes: aspectRatio, height, imageSizing, isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, productId, saleBadgeAlign, scale, showProductLink, showSaleBadge, width
产品价格 - woocommerce/product-price
显示产品的价格。
- Name: woocommerce/product-price
- Category: woocommerce-product-elements
- Ancestor: woocommerce/all-products, woocommerce/featured-product, woocommerce/single-product, woocommerce/product-template, core/post-template
- Parent:
- Supports: color (背景, 文本,
链接), email, interactivity, spacing (间距, padding), typography (fontSize, lineHeight),html - Attributes: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, productId, textAlign
产品 图像 库 - woocommerce/product-image-gallery
显示产品的图像。
- Name: woocommerce/product-image-gallery
- Category: woocommerce-product-elements
- Ancestor:
- Parent:
- Supports: align, interactivity (clientNavigation),
multiple - Attributes:
产品元数据 - woocommerce/product-meta
显示产品的 SKU、分类、标签等信息。
- 名称: woocommerce/product-meta
- 分类: woocommerce-product-elements
- 父级:
- 祖先:
- 支持: 对齐, 交互 (clientNavigation),
可复用 - 属性:
产品评分 - woocommerce/product-rating
显示产品的平均评分。
- 名称: woocommerce/product-rating
- 分类: woocommerce-product-elements
- 父级: woocommerce/all-products, woocommerce/single-product, woocommerce/product-template, core/post-template
- 祖先:
- 支持: 颜色 (文本,
背景,链接), 交互 (clientNavigation), 间距 (外边距, 内边距), 排版 (字体大小) - 属性: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, productId, textAlign
产品评分计数器 - woocommerce/product-rating-counter
显示产品的评论数量。
- 名称: woocommerce/product-rating-counter
- 分类: woocommerce-product-elements
- 父级: woocommerce/single-product
- 祖先:
- 支持: 颜色 (链接,
背景,文本), 交互 (clientNavigation), 间距 (外边距, 内边距), 排版 (字体大小),插入器 - 属性: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, productId, textAlign
产品评分星级 - woocommerce/product-rating-stars
使用星级显示产品的平均评分。
- 名称: woocommerce/product-rating-stars
- 分类: woocommerce-product-elements
- 父级: woocommerce/single-product
- 祖先:
- 支持: 颜色 (文本,
背景,链接), 交互 (clientNavigation), 间距 (外边距, 内边距), 排版 (字体大小),插入器 - 属性: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, productId, textAlign
相关产品 - woocommerce/related-products
显示相关产品。
- 名称: woocommerce/related-products
- 分类: woocommerce
- 父级:
- 祖先:
- 支持: 对齐, 交互 (clientNavigation),
插入器,可复用 - 属性:
促销徽章 - woocommerce/product-sale-badge
如果产品正在促销,则显示促销徽章。
- 名称: woocommerce/product-sale-badge
- 分类: woocommerce-product-elements
- 父级: woocommerce/single-product, woocommerce/product-template, core/post-template, woocommerce/product-gallery
- 祖先:
- 支持: 对齐, 颜色 (背景, 渐变, 文本,
链接), 邮件, 交互 (clientNavigation), 间距 (外边距), 排版 (字体大小, 行高),HTML - 属性: isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, productId
产品 SKU - woocommerce/product-sku
显示产品的 SKU。
- 名称: woocommerce/product-sku
- 分类: woocommerce-product-elements
- 父级: woocommerce/product-meta, woocommerce/all-products, woocommerce/single-product, woocommerce/product-template, core/post-template
- 父类:
- 支持: 颜色 (背景, 文本), 交互 (clientNavigation), 间距 (margin, padding), 排版 (fontSize, lineHeight),
html - 属性: isDescendantOfAllProducts, prefix, productId, showProductSelector, suffix
产品库存指示器 - woocommerce/product-stock-indicator
告知顾客产品是否缺货或处于延期交货状态。 当产品有库存时,此块将被隐藏。
- 名称: woocommerce/product-stock-indicator
- 分类: woocommerce-product-elements
- 父级: woocommerce/all-products, woocommerce/single-product, woocommerce/product-template, core/post-template
- 父类:
- 支持: 颜色 (背景, 文本), 交互, 间距 (margin, padding), 排版 (fontSize, lineHeight),
html - 属性: isDescendantOfAllProducts
产品摘要 - woocommerce/product-summary
显示关于产品的简短描述。
- 名称: woocommerce/product-summary
- 分类: woocommerce-product-elements
- 父级: woocommerce/all-products, woocommerce/featured-product, woocommerce/single-product, woocommerce/product-template, core/post-template
- 父类:
- 支持: 颜色 (背景, 链接, 文本), 交互 (clientNavigation), 间距 (margin, padding), 排版 (fontSize, lineHeight, textAlign)
- 属性: isDescendantOfAllProducts, isDescendentOfQueryLoop, isDescendentOfSingleProductBlock, isDescendentOfSingleProductTemplate, linkText, productId, showDescriptionIfEmpty, showLink, summaryLength
产品标题 - woocommerce/product-title
显示产品的标题。
- 名称: woocommerce/product-title
- 分类: woocommerce-product-elements
- 父级: woocommerce/all-products
- 父类:
- 支持: 颜色 (背景, 渐变, 文本,
链接), 交互 (clientNavigation), 间距 (margin), 排版 (fontSize, lineHeight),html - 属性: align, headingLevel, linkTarget, productId, showProductLink
折叠组 - woocommerce/accordion-group
一组标题和相关的可展开内容。
- 名称: woocommerce/accordion-group
- 分类: woocommerce
- 父级:
- 父类:
- 支持: 对齐 (full, wide), 背景 (backgroundImage, backgroundSize), 颜色 (背景, 渐变, 文本), 交互, 布局, 阴影, 间距 (blockGap, margin, padding),
html - 属性: allowedBlocks, autoclose, iconPosition
折叠标题 - woocommerce/accordion-header
折叠标题。
- Name: woocommerce/accordion-header
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/accordion-item
- Supports: anchor, border, color (background, gradient, text), interactivity, layout, shadow, spacing (margin, padding), typography (fontSize, textAlign),
align - Attributes: icon, iconPosition, level, levelOptions, openByDefault, textAlignment, title
折叠 - woocommerce/accordion-item
一个单独的折叠组件,用于显示标题和可展开的内容。
- Name: woocommerce/accordion-item
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/accordion-group
- Supports: align (full, wide), color (background, gradient, text), interactivity, layout, shadow, spacing (blockGap, margin)
- Attributes: openByDefault
折叠面板 - woocommerce/accordion-panel
折叠面板
- Name: woocommerce/accordion-panel
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/accordion-item
- Supports: border, color (background, gradient, text), interactivity, layout, shadow, spacing (blockGap, margin, padding), typography (fontSize, lineHeight)
- Attributes: allowedBlocks, isSelected, openByDefault, templateLock
激活过滤器控件 - woocommerce/active-filters
显示当前激活的过滤器。
- Name: woocommerce/active-filters
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (text,
background), interactivity (clientNavigation),html,inserter,lock,multiple - Attributes: displayStyle, headingLevel
加入购物车 + 选项 (Beta) - woocommerce/add-to-cart-with-options
使用块来创建“加入购物车”区域,该区域针对不同类型的产品进行定制,例如可变产品和分组产品。
- Name: woocommerce/add-to-cart-with-options
- Category: woocommerce-product-elements
- Ancestor:
- Parent:
- Supports: interactivity
- Attributes: isDescendantOfAddToCartWithOptions
分组产品选择器 (Beta) - woocommerce/add-to-cart-with-options-grouped-product-selector
显示一组可以添加到购物车的的产品。
- Name: woocommerce/add-to-cart-with-options-grouped-product-selector
- Category: woocommerce-product-elements
- Ancestor: woocommerce/add-to-cart-with-options
- Parent:
- Supports: interactivity
- Attributes:
分组产品:模板 (Beta) - woocommerce/add-to-cart-with-options-grouped-product-item
一个列表项目模板,代表分组产品选择器块中的子产品。
- Name: woocommerce/add-to-cart-with-options-grouped-product-item
- Category: woocommerce-product-elements
- Ancestor: woocommerce/add-to-cart-with-options-grouped-product-selector
- Parent:
- Supports: interactivity,
inserter - Attributes:
分组产品:项目标签 (Beta) - woocommerce/add-to-cart-with-options-grouped-product-item-label
以标签或段落的形式显示产品标题。
- 名称: woocommerce/add-to-cart-with-options-grouped-product-item-label
- 分类: woocommerce-product-elements
- 父级: woocommerce/add-to-cart-with-options-grouped-product-item
- 父类:
- 支持: color (background, gradients, text), layout (selfStretch), spacing (blockGap, margin, padding), typography (fontSize, lineHeight, textAlign),
html - 属性:
分组产品:项目选择器 (Beta) - woocommerce/add-to-cart-with-options-grouped-product-item-selector
添加一种在分组产品块中选择子产品的机制。根据产品的类型及其属性,这可能是一个按钮、复选框或链接。
- 名称: woocommerce/add-to-cart-with-options-grouped-product-item-selector
- 分类: woocommerce-product-elements
- 父级: woocommerce/add-to-cart-with-options-grouped-product-item
- 父类:
- 支持: interactivity,
inserter - 属性:
产品数量 (Beta) - woocommerce/add-to-cart-with-options-quantity-selector
显示一个输入字段,客户可以使用该字段选择要添加到购物车的产品的数量。
- 名称: woocommerce/add-to-cart-with-options-quantity-selector
- 分类: woocommerce-product-elements
- 父级: woocommerce/add-to-cart-with-options
- 父类:
- 支持: interactivity
- 属性:
变体描述 (Beta) - woocommerce/add-to-cart-with-options-variation-description
显示所选变体的描述。
- 名称: woocommerce/add-to-cart-with-options-variation-description
- 分类: woocommerce
- 父级: woocommerce/add-to-cart-with-options
- 父类:
- 支持: color (background, gradients, link, text), dimensions (minHeight), interactivity, spacing (margin, padding), typography (fontSize, lineHeight),
html - 属性:
变体选择器:模板 (Beta) - woocommerce/add-to-cart-with-options-variation-selector-attribute
一个用于属性名称和选项的模板,该模板将应用于所有具有属性的可变产品。
- 名称: woocommerce/add-to-cart-with-options-variation-selector-attribute
- 分类: woocommerce-product-elements
- 父级: woocommerce/add-to-cart-with-options-variation-selector
- 父类:
- 支持: interactivity,
inserter - 属性:
可变产品属性选择器:属性名称 (Beta) - woocommerce/add-to-cart-with-options-variation-selector-attribute-name
格式化与可变产品关联的属性名称。
- 名称: woocommerce/add-to-cart-with-options-variation-selector-attribute-name
- 分类: woocommerce-product-elements
- 父元素: woocommerce/add-to-cart-with-options-variation-selector-attribute
- 父级:
- 支持: color (背景, 渐变, 文本), 交互性, 间距 (内边距), 排版 (fontSize, lineHeight),
alignWide,align,inserter - 属性:
可变产品属性选择器:属性选项 (Beta) - woocommerce/add-to-cart-with-options-variation-selector-attribute-options
显示与可变产品关联的属性选项。
- 名称: woocommerce/add-to-cart-with-options-variation-selector-attribute-options
- 分类: woocommerce-product-elements
- 父元素: woocommerce/add-to-cart-with-options-variation-selector-attribute
- 父级:
- 支持: 交互性,
inserter - 属性: optionStyle
可变产品属性选择器 (Beta) - woocommerce/add-to-cart-with-options-variation-selector
显示可供选择的产品变体,并允许用户加入购物车。
- 名称: woocommerce/add-to-cart-with-options-variation-selector
- 分类: woocommerce-product-elements
- 父元素: woocommerce/add-to-cart-with-options
- 父级:
- 支持: 交互性
- 属性:
属性筛选控件 - woocommerce/attribute-filter
允许客户通过选择一个或多个属性(例如颜色)来筛选产品列表。
- 名称: woocommerce/attribute-filter
- 分类: woocommerce
- 父元素:
- 父级:
- 支持: color (文本,
背景),html,inserter,interactivity,lock - 属性: attributeId, className, displayStyle, headingLevel, isPreview, queryType, selectType, showCounts, showFilterButton
商店面包屑 - woocommerce/breadcrumbs
帮助客户跟踪他们在商店中的位置,并返回到父级网页。
- 名称: woocommerce/breadcrumbs
- 分类: woocommerce
- 父元素:
- 父级:
- 支持: align (full, wide), color (链接, 文本,
背景), 交互性 (clientNavigation), 排版 (fontSize, lineHeight),html - 属性: align, contentJustification, fontSize
已接受的付款方式 - woocommerce/cart-accepted-payment-methods-block
显示已接受的付款方式。
- 名称: woocommerce/cart-accepted-payment-methods-block
- 分类: woocommerce
- 父元素:
- 父级: woocommerce/cart-totals-block
- 支持: inserter,
align,html,multiple,reusable - 属性:
购物车交叉销售 - woocommerce/cart-cross-sells-block
显示交叉销售模块。
- Name: woocommerce/cart-cross-sells-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-items-block
- Supports:
align,html,inserter,multiple,reusable - Attributes:
购物车交叉销售产品 - woocommerce/cart-cross-sells-products-block
显示交叉销售产品。
- Name: woocommerce/cart-cross-sells-products-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-cross-sells-block
- Supports: email,
align,html,inserter,lock,multiple,reusable - Attributes: columns, lock
快速结账 - woocommerce/cart-express-payment-block
允许客户通过快速支付选项轻松完成购物。
- Name: woocommerce/cart-express-payment-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-totals-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: buttonBorderRadius, buttonHeight, lock, showButtonStyles
购物车商品 - woocommerce/cart-items-block
包含购物车商品的列。
- Name: woocommerce/cart-items-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/filled-cart-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
购物车商品明细 - woocommerce/cart-line-items-block
包含购物车当前商品明细的模块。
- Name: woocommerce/cart-line-items-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-items-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
订单摘要 - woocommerce/cart-order-summary-block
向客户显示其订单的摘要。
- Name: woocommerce/cart-order-summary-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-totals-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
优惠券表单 - woocommerce/cart-order-summary-coupon-form-block
显示应用优惠券的表单。
- Name: woocommerce/cart-order-summary-coupon-form-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-block
- Supports:
align,html,multiple,reusable - Attributes: className, lock
折扣 - woocommerce/cart-order-summary-discount-block
显示购物车折扣行。
- Name: woocommerce/cart-order-summary-discount-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-totals-block
- Supports:
align,html,lock,multiple,reusable - Attributes: className, lock
Fees - woocommerce/cart-order-summary-fee-block
显示购物车费用行。
- Name: woocommerce/cart-order-summary-fee-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-totals-block
- Supports:
align,html,lock,multiple,reusable - 属性: className, lock
Heading - woocommerce/cart-order-summary-heading-block
显示标题行。
- Name: woocommerce/cart-order-summary-heading-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-block
- Supports:
align,html,multiple,reusable - 属性: className, content, lock
Shipping - woocommerce/cart-order-summary-shipping-block
显示购物车配送行。
- Name: woocommerce/cart-order-summary-shipping-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-totals-block
- Supports:
align,html,lock,multiple,reusable - 属性: lock
Subtotal - woocommerce/cart-order-summary-subtotal-block
显示购物车小计行。
- Name: woocommerce/cart-order-summary-subtotal-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-totals-block
- Supports:
align,html,lock,multiple,reusable - 属性: className, lock
Taxes - woocommerce/cart-order-summary-taxes-block
显示购物车税费行。
- Name: woocommerce/cart-order-summary-taxes-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-totals-block
- Supports:
align,html,lock,multiple,reusable - 属性: className, lock
Totals - woocommerce/cart-order-summary-totals-block
显示小计、费用、折扣、配送和税费。
- Name: woocommerce/cart-order-summary-totals-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart-order-summary-block
- Supports:
align,html,lock,multiple,reusable - 属性: className, lock
Cart Totals - woocommerce/cart-totals-block
包含购物车总计的列。
- Name: woocommerce/cart-totals-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/filled-cart-block
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: checkbox, lock, text
Empty Cart - woocommerce/empty-cart-block
包含在购物车为空时显示的块。
- Name: woocommerce/empty-cart-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/cart
- Supports: align (wide),
html,inserter,lock,multiple,reusable - 属性: lock
购物车内容 - woocommerce/filled-cart-block
包含在购物车包含产品时显示的模块。
- Name: woocommerce/filled-cart-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart
- Supports: align (wide),
html,inserter,lock,multiple,reusable - Attributes: lock
继续结账 - woocommerce/proceed-to-checkout-block
允许客户继续结账。
- Name: woocommerce/proceed-to-checkout-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/cart-totals-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
购物车链接 - woocommerce/cart-link
显示链接至购物车的链接。
- Name: woocommerce/cart-link
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (background, link,
text), interactivity (clientNavigation), spacing (padding), typography (fontSize),html,multiple - Attributes: cartIcon, content, isPreview
产品分类排序 - woocommerce/catalog-sorting
允许客户更改产品的排序顺序。
- Name: woocommerce/catalog-sorting
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (text,
background), interactivity (clientNavigation), typography (fontSize) - Attributes: fontSize, useLabel
产品分类描述 - woocommerce/category-description
显示当前的分类描述。
- Name: woocommerce/category-description
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (background, text), spacing (margin, padding), typography,
align,html - Attributes: textAlign
产品分类标题 - woocommerce/category-title
显示当前的分类标题,并允许授权用户编辑它。
- Name: woocommerce/category-title
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (background, text), spacing (margin, padding), typography,
align,html - Attributes: isLink, level, linkTarget, rel, textAlign
结账 - woocommerce/checkout
显示结账表单,以便您的客户可以提交订单。
- Name: woocommerce/checkout
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (wide),
html,multiple - Attributes: align, isPreview, showFormStepNumbers
操作 - woocommerce/checkout-actions-block
允许客户提交他们的订单。
- Name: woocommerce/checkout-actions-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: cartPageId, className, lock, priceSeparator, showReturnToCart
其他信息 - woocommerce/checkout-additional-information-block
在 '其他信息' 的位置渲染附加字段。
- Name: woocommerce/checkout-additional-information-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,multiple,reusable - 属性: className, lock
账单地址 - woocommerce/checkout-billing-address-block
收集客户的账单地址。
- Name: woocommerce/checkout-billing-address-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: lock
联系信息 - woocommerce/checkout-contact-information-block
收集客户的联系信息。
- Name: woocommerce/checkout-contact-information-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: lock
快捷结账 - woocommerce/checkout-express-payment-block
允许客户通过快速支付选项简化结账流程。
- Name: woocommerce/checkout-express-payment-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: buttonBorderRadius, buttonHeight, className, lock, showButtonStyles
结账字段 - woocommerce/checkout-fields-block
包含结账地址字段的列。
- Name: woocommerce/checkout-fields-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: className, lock
订单备注 - woocommerce/checkout-order-note-block
允许客户向他们的订单添加备注。
- Name: woocommerce/checkout-order-note-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,multiple,reusable - 属性: className, lock
订单摘要 - woocommerce/checkout-order-summary-block
向客户展示他们订单的摘要。
- Name: woocommerce/checkout-order-summary-block
- 分类: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-totals-block
- Supports:
align,html,inserter,lock,multiple,reusable - 属性: lock
购物车项目 - woocommerce/checkout-order-summary-cart-items-block
显示购物车项目。
- 名称: woocommerce/checkout-order-summary-cart-items-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, disableProductDescriptions, lock
优惠券表单 - woocommerce/checkout-order-summary-coupon-form-block
显示应用优惠券的表单。
- 名称: woocommerce/checkout-order-summary-coupon-form-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-block
- 支持:
align,html,multiple,reusable - 属性: className, lock
折扣 - woocommerce/checkout-order-summary-discount-block
显示购物车折扣行。
- 名称: woocommerce/checkout-order-summary-discount-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-totals-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, lock
费用 - woocommerce/checkout-order-summary-fee-block
显示购物车费用行。
- 名称: woocommerce/checkout-order-summary-fee-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-totals-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, lock
配送 - woocommerce/checkout-order-summary-shipping-block
显示购物车配送行。
- 名称: woocommerce/checkout-order-summary-shipping-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-totals-block
- 支持:
align,html,lock,multiple,reusable - 属性: lock
小计 - woocommerce/checkout-order-summary-subtotal-block
显示购物车小计行。
- 名称: woocommerce/checkout-order-summary-subtotal-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-totals-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, lock
税费 - woocommerce/checkout-order-summary-taxes-block
显示购物车税费行。
- 名称: woocommerce/checkout-order-summary-taxes-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-totals-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, lock
总计 - woocommerce/checkout-order-summary-totals-block
显示小计、费用、折扣、配送和税费。
- 名称: woocommerce/checkout-order-summary-totals-block
- 分类: woocommerce
- 父级:
- 父类: woocommerce/checkout-order-summary-block
- 支持:
align,html,lock,multiple,reusable - 属性: className, lock
支付方式 - woocommerce/checkout-payment-block
您商店的支付方式。
- Name: woocommerce/checkout-payment-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
取货方式 - woocommerce/checkout-pickup-options-block
显示本地自提的位置。
- Name: woocommerce/checkout-pickup-options-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
收货地址 - woocommerce/checkout-shipping-address-block
收集客户的收货地址。
- Name: woocommerce/checkout-shipping-address-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
配送方式 - woocommerce/checkout-shipping-method-block
选择配送或本地自提。
- Name: woocommerce/checkout-shipping-method-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
配送选项 - woocommerce/checkout-shipping-methods-block
显示您商店的配送选项和运费。
- Name: woocommerce/checkout-shipping-methods-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: lock
条款和条件 - woocommerce/checkout-terms-block
确保客户同意您的条款和条件以及隐私政策。
- Name: woocommerce/checkout-terms-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout-fields-block
- Supports:
align,html,multiple,reusable - Attributes: checkbox, className, showSeparator, text
订单总计 - woocommerce/checkout-totals-block
包含订单总计的列。
- Name: woocommerce/checkout-totals-block
- Category: woocommerce
- Ancestor:
- Parent: woocommerce/checkout
- Supports:
align,html,inserter,lock,multiple,reusable - Attributes: checkbox, className, text
经典短代码 - woocommerce/classic-shortcode
渲染经典 WooCommerce 短代码。
- Name: woocommerce/classic-shortcode
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align, inserter, interactivity (
clientNavigation),html,multiple,reusable - Attributes: align, shortcode
即将推出 - woocommerce/coming-soon
- Name: woocommerce/coming-soon
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (背景, 文本),
插入器 - Attributes: color, comingSoonPatternId, storeOnly
客户账户 - woocommerce/customer-account
一个允许您的客户登录和退出您商店账户的块。
- Name: woocommerce/customer-account
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align, color (背景, 文本), interactivity (客户端导航), spacing (边距, 内边距), typography (字体大小)
- Attributes: displayStyle, iconClass, iconStyle
邮件内容 - woocommerce/email-content
一个用于邮件内容的占位符块。
- Name: woocommerce/email-content
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: email,
插入器 - Attributes: emailType, postId
推荐分类 - woocommerce/featured-category
视觉上突出显示一个产品分类,并鼓励用户立即采取行动。
- Name: woocommerce/featured-category
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (全屏, 宽屏), ariaLabel, color (背景, 文本), filter (双色), interactivity (客户端导航), spacing (内边距),
HTML - Attributes: alt, categoryId, contentAlign, dimRatio, focalPoint, hasParallax, imageFit, isRepeated, linkText, mediaId, mediaSrc, minHeight, overlayColor, overlayGradient, previewCategory
推荐产品 - woocommerce/featured-product
突出显示一个产品或变体。
- Name: woocommerce/featured-product
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (全屏, 宽屏), ariaLabel, color (背景, 文本), filter (双色), interactivity (客户端导航), multiple, spacing (内边距),
HTML - Attributes: alt, contentAlign, dimRatio, focalPoint, hasParallax, imageFit, isRepeated, linkText, mediaId, mediaSrc, minHeight, overlayColor, overlayGradient, previewProduct, productId
筛选块 - woocommerce/filter-wrapper
- Name: woocommerce/filter-wrapper
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: interactivity (客户端导航),
插入器 - Attributes: filterType, heading
精选产品 - woocommerce/handpicked-products
以网格形式显示精选产品。
- Name: woocommerce/handpicked-products
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (全屏, 宽屏), interactivity (客户端导航),
HTML,插入器 - Attributes: align, alignButtons, columns, contentVisibility, isPreview, orderby, products
Mini-Cart - woocommerce/mini-cart
显示一个按钮,方便购物者快速查看购物车。
- 名称: woocommerce/mini-cart
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: 间距 (margin, padding), 字体 (fontSize),
HTML,多选 - 属性: addToCartBehaviour, cartAndCheckoutRenderStyle, hasHiddenPrice, iconColor, iconColorValue, isPreview, miniCartIcon, onCartClickBehaviour, priceColor, priceColorValue, productCountColor, productCountColorValue, productCountVisibility
Mini-Cart 内容 - woocommerce/mini-cart-contents
显示一个迷你购物车组件。
- 名称: woocommerce/mini-cart-contents
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: 颜色 (背景, 链接, 文本),
对齐,HTML,插入器,锁定,多选,可重用 - 属性: isPreview, lock, 宽度
迷你购物车为空时的视图 - woocommerce/empty-mini-cart-contents-block
当迷你购物车为空时显示的块。
- 名称: woocommerce/empty-mini-cart-contents-block
- 分类: woocommerce
- 父级:
- 祖父级: woocommerce/mini-cart-contents
- 支持: 交互性,
对齐,HTML,插入器,锁定,多选,可重用 - 属性: lock
迷你购物车已填充时的视图 - woocommerce/filled-mini-cart-contents-block
包含显示迷你购物车内容的块。
- 名称: woocommerce/filled-mini-cart-contents-block
- 分类: woocommerce
- 父级:
- 祖父级: woocommerce/mini-cart-contents
- 支持: 交互性,
对齐,HTML,插入器,锁定,多选,可重用 - 属性: lock
迷你购物车“查看购物车”按钮 - woocommerce/mini-cart-cart-button-block
当迷你购物车包含产品时,显示购物车按钮的块。
- 名称: woocommerce/mini-cart-cart-button-block
- 分类: woocommerce
- 父级:
- 祖父级: woocommerce/mini-cart-footer-block
- 支持: 颜色 (背景, 文本), 插入器, 交互性 (clientNavigation),
对齐,HTML,多选,可重用 - 属性: cartButtonLabel, lock
迷你购物车“继续结账”按钮 - woocommerce/mini-cart-checkout-button-block
当迷你购物车包含产品时,显示结账按钮的块。
- 名称: woocommerce/mini-cart-checkout-button-block
- 分类: woocommerce
- 父级:
- 祖父级: woocommerce/mini-cart-footer-block
- 支持: 颜色 (背景, 文本), 插入器, 交互性 (clientNavigation),
对齐,HTML,多选,可重用 - 属性: checkoutButtonLabel, lock
Mini-Cart 底部 - woocommerce/mini-cart-footer-block
显示 Mini-Cart 块的底部的块。
- 名称: woocommerce/mini-cart-footer-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/filled-mini-cart-contents-block
- 支持: 交互性,
对齐,HTML,插入器,锁定,多选,可复用 - 属性: 锁定
Mini-Cart 项目 - woocommerce/mini-cart-items-block
包含填充 Mini-Cart 的产品表格和其他自定义块。
- 名称: woocommerce/mini-cart-items-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/filled-mini-cart-contents-block
- 支持: 交互性 (clientNavigation),
对齐,HTML,插入器,锁定,多选,可复用 - 属性: 锁定
Mini-Cart 产品表格 - woocommerce/mini-cart-products-table-block
显示 Mini-Cart 块的产品表格的块。
- 名称: woocommerce/mini-cart-products-table-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/mini-cart-items-block
- 支持: 交互性,
对齐,HTML,插入器,锁定,多选,可复用 - 属性: 锁定
Mini-Cart 购物按钮 - woocommerce/mini-cart-shopping-button-block
当 Mini-Cart 为空时,显示购物按钮的块。
- 名称: woocommerce/mini-cart-shopping-button-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/empty-mini-cart-contents-block
- 支持: 颜色 (背景, 文本), 插入器, 交互性 (clientNavigation),
对齐,HTML,多选,可复用 - 属性: 锁定, startShoppingButtonLabel
Mini-Cart 标题 - woocommerce/mini-cart-title-block
显示 Mini-Cart 块的标题的块。
- 名称: woocommerce/mini-cart-title-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/filled-mini-cart-contents-block
- 支持: 颜色 (文本,
背景), 交互性 (clientNavigation), 排版 (字体大小),对齐,HTML,插入器,锁定,多选,可复用 - 属性: 锁定
Mini-Cart 标题 项目计数器 - woocommerce/mini-cart-title-items-counter-block
显示 Mini-Cart 标题部分的项目计数器的块。
- 名称: woocommerce/mini-cart-title-items-counter-block
- 分类: woocommerce
- 父级:
- 父块: woocommerce/mini-cart-title-block
- 支持: 颜色 (背景, 文本), 交互性, 间距 (内边距), 排版 (字体大小),
对齐,HTML,插入器,锁定,多选,可复用 - 属性:
Mini-Cart Title Label - woocommerce/mini-cart-title-label-block
用于显示迷你购物车标题部分的模块。
- 名称: woocommerce/mini-cart-title-label-block
- 分类: woocommerce
- 父模块:
- 父级: woocommerce/mini-cart-title-block
- 支持: color (背景, 文本), interactivity (客户端导航), spacing (内边距), typography (字体大小),
align,html,inserter,lock,multiple,reusable - 属性: label
Next/Previous Buttons - woocommerce/product-gallery-large-image-next-previous
显示“下一张”和“上一张”按钮。
- 名称: woocommerce/product-gallery-large-image-next-previous
- 分类: woocommerce
- 父模块: woocommerce/product-gallery-large-image, woocommerce/product-collection
- 父级:
- 支持: align, color (背景, 文本), interactivity, layout (允许垂直对齐, 默认,
允许对齐,允许方向), shadow, spacing (外边距) - 属性:
Additional Field List - woocommerce/order-confirmation-additional-fields
显示当前订单的附加字段值列表。
- 名称: woocommerce/order-confirmation-additional-fields
- 分类: woocommerce
- 父模块:
- 父级:
- 支持: align (全屏, 宽屏), spacing (外边距, 内边距),
html,multiple - 属性: align, className
Additional Fields - woocommerce/order-confirmation-additional-fields-wrapper
显示来自“联系方式”和“订单”位置的附加结账字段。
- 名称: woocommerce/order-confirmation-additional-fields-wrapper
- 分类: woocommerce
- 父模块:
- 父级:
- 支持: align (全屏, 宽屏), spacing (外边距, 内边距),
html,multiple - 属性: heading
Additional Information - woocommerce/order-confirmation-additional-information
显示由第三方扩展提供的当前订单的附加信息。
- 名称: woocommerce/order-confirmation-additional-information
- 分类: woocommerce
- 父模块:
- 父级:
- 支持: align (全屏, 宽屏), spacing (外边距, 内边距),
html,multiple - 属性: align, className
Billing Address - woocommerce/order-confirmation-billing-address
显示订单确认的账单地址。
- 名称: woocommerce/order-confirmation-billing-address
- 分类: woocommerce
- 父模块:
- 父级:
- 支持: align (全屏, 宽屏), color (背景, 文本), spacing (外边距, 内边距), typography (字体大小, 行高),
html,inserter,multiple - 属性: align
账单地址 - woocommerce/order-confirmation-billing-wrapper
显示订单确认页面的账单地址部分。
- Name: woocommerce/order-confirmation-billing-wrapper
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), spacing (margin, padding),
html,multiple - Attributes: heading
账户创建 - woocommerce/order-confirmation-create-account
允许客户在购买后创建账户。
- Name: woocommerce/order-confirmation-create-account
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), color (background, button, text), spacing (margin, padding),
html,inserter,lock,multiple - Attributes: align, className, customerEmail, hasDarkControls, lock, nonceToken
订单下载 - woocommerce/order-confirmation-downloads
显示已购买的下载链接。
- Name: woocommerce/order-confirmation-downloads
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight),
html,multiple - Attributes: align, className
下载部分 - woocommerce/order-confirmation-downloads-wrapper
显示可下载产品部分。
- Name: woocommerce/order-confirmation-downloads-wrapper
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), spacing (margin, padding),
html,multiple - Attributes: heading
配送地址 - woocommerce/order-confirmation-shipping-address
显示订单确认页面的配送地址。
- Name: woocommerce/order-confirmation-shipping-address
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), color (background, text), spacing (margin, padding), typography (fontSize, lineHeight),
html,inserter,multiple - Attributes: align
配送地址部分 - woocommerce/order-confirmation-shipping-wrapper
显示订单确认页面的配送部分。
- Name: woocommerce/order-confirmation-shipping-wrapper
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), spacing (margin, padding),
html,multiple - Attributes: heading
订单状态 - woocommerce/order-confirmation-status
显示“谢谢”消息,或关于当前订单状态的句子。
- Name: woocommerce/order-confirmation-status
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), color (background, gradients, text), spacing (margin, padding), typography (fontSize, lineHeight),
html,multiple - Attributes: align, className
订单摘要 - woocommerce/order-confirmation-summary
在订单确认页面显示订单摘要。
- 名称: woocommerce/order-confirmation-summary
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: align (full, wide), color (background, gradients, text), spacing (margin, padding), typography (fontSize, lineHeight),
html,multiple - 属性: align, className
订单总计 - woocommerce/order-confirmation-totals
显示已购买的商品和订单总计。
- 名称: woocommerce/order-confirmation-totals
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: align (full, wide), color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight),
html,multiple - 属性: align, className
订单总计部分 - woocommerce/order-confirmation-totals-wrapper
显示订单详情部分。
- 名称: woocommerce/order-confirmation-totals-wrapper
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: align (full, wide), spacing (margin, padding),
html,multiple - 属性: heading
WooCommerce 网页 - woocommerce/page-content-wrapper
显示 WooCommerce 网页内容。
- 名称: woocommerce/page-content-wrapper
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持:
html,inserter,multiple - 属性: page
付款方式图标 - woocommerce/payment-method-icons
显示可用付款方式的图标。
- 名称: woocommerce/payment-method-icons
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: spacing (margin, padding)
- 属性: numberOfIcons
按价格筛选控件 - woocommerce/price-filter
允许客户通过选择价格范围来筛选商品列表。
- 名称: woocommerce/price-filter
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: color (text,
background), interactivity (clientNavigation),html,inserter,lock,multiple - 属性: className, headingLevel, inlineInput, showFilterButton, showInputFields
最畅销商品 - woocommerce/product-best-sellers
显示您所有时期的最畅销商品列表。
- 名称: woocommerce/product-best-sellers
- 分类: woocommerce
- 父级:
- 祖父级:
- 支持: align (full, wide), interactivity (
clientNavigation),html,inserter - 属性: alignButtons, catOperator, categories, columns, contentVisibility, editMode, isPreview, orderby, rows, stockStatus
产品分类列表 - woocommerce/product-categories
以列表或下拉形式显示所有产品分类。
- 名称: woocommerce/product-categories
- 分类: woocommerce
- 父分类:
- 父级:
- 支持: align (full, wide), color (link, text,
background), interactivity (clientNavigation), typography (fontSize, lineHeight),html - 属性: align, hasCount, hasEmpty, hasImage, isDropdown, isHierarchical, showChildrenOnly
按分类的产品 - woocommerce/product-category
显示来自您所选分类的产品网格。
- 名称: woocommerce/product-category
- 分类: woocommerce
- 父分类:
- 父级:
- 支持: align (full, wide), interactivity (
clientNavigation),html,inserter - 属性: alignButtons, catOperator, categories, columns, contentVisibility, editMode, isPreview, orderby, rows, stockStatus
产品集合 - woocommerce/product-collection
显示您商店中的产品集合。
- 名称: woocommerce/product-collection
- 分类: woocommerce
- 父分类:
- 父级:
- 支持: align (full, wide), anchor, email, interactivity,
html - 属性: __privatePreviewState, collection, convertedFromProducts, dimensions, displayLayout, forcePageReload, hideControls, query, queryContextIncludes, queryId, tagName
无结果 - woocommerce/product-collection-no-results
当未找到任何产品时,此块的内容将显示。
- 名称: woocommerce/product-collection-no-results
- 分类: woocommerce
- 父分类: woocommerce/product-collection
- 父级:
- 支持: align, color (background, gradients, link, text), email, interactivity (clientNavigation), typography (fontSize, lineHeight),
html,reusable - 属性:
产品描述 - woocommerce/product-description
显示产品的描述。
- 名称: woocommerce/product-description
- 分类: woocommerce
- 父分类: woocommerce/single-product, woocommerce/product-template, core/post-template
- 父级:
- 支持: align (full, wide), background (backgroundImage, backgroundSize), color (background, gradients, heading, link, text), dimensions (minHeight), interactivity (clientNavigation), layout, spacing (blockGap, margin, padding), typography (fontSize, lineHeight),
html - 属性:
产品详情 - woocommerce/product-details
显示产品的描述、属性和评论。
- 名称: woocommerce/product-details
- 分类: woocommerce
- 父分类:
- 父级:
- 支持: align (full, wide), interactivity (clientNavigation)
- 属性: align, hideTabTitle
加入购物车 - woocommerce/add-to-cart-form
显示一个按钮,允许客户将产品添加到购物车。使用添加的选项来优化不同类型的产品。
- 名称: woocommerce/add-to-cart-form
- 分类: woocommerce-product-elements
- 父级:
- 祖先:
- 支持: 交互性
- 属性: quantitySelectorStyle
产品筛选器 - woocommerce/product-filters
允许购物者筛选网页上显示的商品。
- 名称: woocommerce/product-filters
- 分类: woocommerce
- 父级:
- 祖先:
- 支持: 对齐, 颜色 (背景, 按钮, 标题, 文本,
启用对比检查器), 插入器, 交互性, 布局 (默认,允许编辑), 多选, 间距 (块间距), 排版 (字体大小) - 属性: isPreview
激活的筛选器 - woocommerce/product-filter-active
显示当前激活的筛选器。
- 名称: woocommerce/product-filter-active
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 祖先:
- 支持: 交互性, 间距 (边距, 内边距,
块间距) - 属性:
属性筛选器 - woocommerce/product-filter-attribute
允许客户通过选择一个或多个属性(例如颜色)来筛选产品列表。
- 名称: woocommerce/product-filter-attribute
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 祖先:
- 支持: 颜色 (文本,
背景), 交互性, 间距 (块间距, 边距, 内边距), 排版 (字体大小, 行高) - 属性: attributeId, displayStyle, hideEmpty, isPreview, queryType, selectType, showCounts, sortOrder
列表 - woocommerce/product-filter-checkbox-list
显示一个筛选选项列表。
- 名称: woocommerce/product-filter-checkbox-list
- 分类: woocommerce
- 父级: woocommerce/product-filter-attribute, woocommerce/product-filter-status, woocommerce/product-filter-taxonomy, woocommerce/product-filter-rating
- 祖先:
- 支持: 交互性
- 属性: customLabelElement, customOptionElement, customOptionElementBorder, customOptionElementSelected, labelElement, optionElement, optionElementBorder, optionElementSelected
标签 - woocommerce/product-filter-chips
以标签的形式显示筛选选项。
- 名称: woocommerce/product-filter-chips
- 分类: woocommerce
- 父级: woocommerce/product-filter-attribute, woocommerce/product-filter-taxonomy, woocommerce/product-filter-status
- 祖先:
- 支持: 交互性
- 属性: chipBackground, chipBorder, chipText, customChipBackground, customChipBorder, customChipText, customSelectedChipBackground, customSelectedChipBorder, customSelectedChipText, selectedChipBackground, selectedChipBorder, selectedChipText
清除过滤器 - woocommerce/product-filter-clear-button
允许购物者清除已应用的过滤器。
- 名称: woocommerce/product-filter-clear-button
- 分类: woocommerce
- 父级: woocommerce/product-filter-active
- 父分类:
- 支持: inserter, interactivity
- 属性:
价格过滤器 - woocommerce/product-filter-price
允许购物者通过选择价格范围来过滤产品。
- 名称: woocommerce/product-filter-price
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 父分类:
- 支持: interactivity,
html - 属性:
价格滑块 - woocommerce/product-filter-price-slider
滑块帮助购物者选择价格范围。
- 名称: woocommerce/product-filter-price-slider
- 分类: woocommerce
- 父级: woocommerce/product-filter-price
- 父分类:
- 支持: color (
背景,enableContrastChecker,文本), interactivity,html - 属性: customSlider, customSliderHandle, customSliderHandleBorder, inlineInput, showInputFields, slider, sliderHandle, sliderHandleBorder
评分过滤器 - woocommerce/product-filter-rating
允许客户根据评分来过滤产品集合。
- 名称: woocommerce/product-filter-rating
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 父分类:
- 支持: color (文本,
背景), interactivity - 属性: className, isPreview, minRating, showCounts
标签 - woocommerce/product-filter-removable-chips
以标签的形式显示可移除的已应用过滤器。
- 名称: woocommerce/product-filter-removable-chips
- 分类: woocommerce
- 父级: woocommerce/product-filter-active
- 父分类:
- 支持: interactivity, layout (默认,
allowInheriting,allowSwitching,allowVerticalAlignment) - 属性: chipBackground, chipBorder, chipText, customChipBackground, customChipBorder, customChipText
状态过滤器 - woocommerce/product-filter-status
允许购物者通过选择库存状态来过滤产品。
- 名称: woocommerce/product-filter-status
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 父分类:
- 支持: color (文本,
背景), interactivity, spacing (blockGap, margin, padding), typography (fontSize, lineHeight),html - 属性: displayStyle, hideEmpty, isPreview, showCounts
分类法过滤器 - woocommerce/product-filter-taxonomy
允许客户通过选择一个或多个分类法项来过滤产品集合,例如分类、品牌或标签。
- 名称: woocommerce/product-filter-taxonomy
- 分类: woocommerce
- 父级: woocommerce/product-filters
- 父分类:
- 支持: color (文本,
背景), interactivity, spacing (blockGap, margin, padding), typography (fontSize, lineHeight) - 属性: displayStyle, hideEmpty, isPreview, showCounts, sortOrder, taxonomy
产品画廊 - woocommerce/product-gallery
展示您的产品相关的图片和媒体。
- 名称: woocommerce/product-gallery
- 分类: woocommerce
- 父级: woocommerce/single-product
- 父分类:
- 支持: align, email, interactivity, layout (allowEditing, allowOrientation, default,
allowJustification) - 属性: fullScreenOnClick, hoverZoom
缩略图 - woocommerce/product-gallery-large-image
显示产品的缩略图。
- 名称: woocommerce/product-gallery-large-image
- 分类: woocommerce
- 父级: woocommerce/product-gallery
- 父分类:
- 支持: interactivity
- 属性:
缩略图 - woocommerce/product-gallery-thumbnails
显示产品的缩略图。
- 名称: woocommerce/product-gallery-thumbnails
- 分类: woocommerce
- 父级: woocommerce/product-gallery
- 父分类:
- 支持: interactivity, spacing (margin)
- 属性: aspectRatio, thumbnailSize
最新产品 - woocommerce/product-new
显示您的最新产品网格。
- 名称: woocommerce/product-new
- 分类: woocommerce
- 父级:
- 父分类:
- 支持: align (full, wide), interactivity (
clientNavigation),html,inserter - 属性: alignButtons, catOperator, categories, columns, contentVisibility, editMode, isPreview, orderby, rows, stockStatus
促销产品 - woocommerce/product-on-sale
显示当前正在促销的产品网格。
- 名称: woocommerce/product-on-sale
- 分类: woocommerce
- 父级:
- 父分类:
- 支持: align (full, wide), interactivity (
clientNavigation),html,inserter - 属性: alignButtons, catOperator, categories, columns, contentVisibility, isPreview, orderby, rows, stockStatus
产品结果数量 - woocommerce/product-results-count
显示存档页面或搜索结果页面上的产品数量。
- 名称: woocommerce/product-results-count
- 分类: woocommerce
- 父级:
- 父分类:
- 支持: color (text,
background), interactivity (clientNavigation), typography (fontSize) - 属性:
产品评论 - woocommerce/product-reviews
显示产品的评论。
- 名称: woocommerce/product-reviews
- 分类: woocommerce
- 父级:
- 父分类:
- 支持: align (full, wide), color (background, gradients, heading, link, text), interactivity, spacing (margin, padding), typography (fontSize, lineHeight),
html - 属性: tagName
评论作者姓名 - woocommerce/product-review-author-name
显示评论的作者姓名。
- 名称: woocommerce/product-review-author-name
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父类:
- 支持: 颜色 (背景, 渐变, 链接, 文本), 交互 (客户端导航), 间距 (边距, 内边距), 排版 (字体大小, 行高),
HTML - 属性: isLink, linkTarget, textAlign
评论内容 - woocommerce/product-review-content
显示产品评论的内容。
- 名称: woocommerce/product-review-content
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父类:
- 支持: 颜色 (背景, 渐变, 链接, 文本), 间距 (内边距), 排版 (字体大小, 行高),
HTML - 属性: textAlign
评论日期 - woocommerce/product-review-date
显示评论发布的日期。
- 名称: woocommerce/product-review-date
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父类:
- 支持: 颜色 (背景, 渐变, 链接, 文本), 交互 (客户端导航), 间距 (边距, 内边距), 排版 (字体大小, 行高),
HTML - 属性: format, isLink
评论表单 - woocommerce/product-review-form
显示产品的评论表单。
- 名称: woocommerce/product-review-form
- 分类: woocommerce
- 父级:
- 父类:
- 支持: 颜色 (背景, 渐变, 标题, 链接, 文本), 交互, 间距 (边距, 内边距), 排版 (字体大小, 行高),
HTML - 属性: textAlign
评论评分 - woocommerce/product-review-rating
显示产品评论的评分。
- 名称: woocommerce/product-review-rating
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父类:
- 支持: 颜色 (背景, 渐变, 文本), 交互 (客户端导航)
- 属性: textAlign
评论模板 - woocommerce/product-review-template
包含用于显示产品评论的块元素,例如标题、作者、日期、评分等。
- 名称: woocommerce/product-review-template
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父类:
- 支持: 对齐, 交互 (客户端导航), 间距 (边距, 内边距), 排版 (字体大小, 行高),
HTML,可复用 - 属性:
评论分页 - woocommerce/product-reviews-pagination
显示分页导航,用于显示下一组或上一组产品评论,如果适用。
- 名称: woocommerce/product-reviews-pagination
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父分类:
- 支持: align, color (background, gradients, link, text), interactivity (clientNavigation), layout (default,
allowInheriting,allowSwitching), typography (fontSize, lineHeight),html,reusable - 属性: paginationArrow
评论下一页 - woocommerce/product-reviews-pagination-next
显示下一篇产品评论的页面链接。
- 名称: woocommerce/product-reviews-pagination-next
- 分类: woocommerce
- 父级: woocommerce/product-reviews-pagination
- 父分类:
- 支持: color (background, gradients,
text), interactivity (clientNavigation), typography (fontSize, lineHeight),html,reusable - 属性: label
评论页码 - woocommerce/product-reviews-pagination-numbers
显示产品评论分页的页码列表。
- 名称: woocommerce/product-reviews-pagination-numbers
- 分类: woocommerce
- 父级: woocommerce/product-reviews-pagination
- 父分类:
- 支持: color (background, gradients,
text), interactivity (clientNavigation), typography (fontSize, lineHeight),html,reusable - 属性:
评论上一页 - woocommerce/product-reviews-pagination-previous
显示上一篇产品评论的页面链接。
- 名称: woocommerce/product-reviews-pagination-previous
- 分类: woocommerce
- 父级: woocommerce/product-reviews-pagination
- 父分类:
- 支持: color (background, gradients,
text), interactivity (clientNavigation), typography (fontSize, lineHeight),html,reusable - 属性: label
评论标题 - woocommerce/product-reviews-title
显示包含评论数量的标题。
- 名称: woocommerce/product-reviews-title
- 分类: woocommerce
- 父级: woocommerce/product-reviews
- 父分类:
- 支持: align, color (background, gradients, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight),
anchor,html - 属性: level, levelOptions, showProductTitle, showReviewsCount, textAlign
产品规格 - woocommerce/product-specifications
显示产品的重量、尺寸和属性。
- 名称: woocommerce/product-specifications
- 分类: woocommerce
- 父级: woocommerce/single-product, woocommerce/product-template, core/post-template
- 父分类:
- 支持: align (full, wide), spacing (margin, padding), typography (fontSize, lineHeight),
html - 属性: showAttributes, showDimensions, showWeight
按照标签的产品 - woocommerce/product-tag
显示带有所选标签的产品网格。
- Name: woocommerce/product-tag
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), interactivity (
clientNavigation),html,inserter - Attributes: alignButtons, columns, contentVisibility, isPreview, orderby, rows, stockStatus, tagOperator, tags
产品模板 - woocommerce/product-template
包含用于渲染产品的块元素。
- Name: woocommerce/product-template
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), anchor, color (background, gradients, link, text), email, interactivity, layout (
allowEditing,allowInheriting,allowSizingOnChildren,allowSwitching,allowVerticalAlignment), typography (fontSize, lineHeight),html,inserter,reusable - Attributes:
顶级产品 - woocommerce/product-top-rated
显示您评价最高的产品的网格。
- Name: woocommerce/product-top-rated
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), interactivity (
clientNavigation),html,inserter - Attributes: alignButtons, catOperator, categories, columns, contentVisibility, editMode, isPreview, orderby, rows, stockStatus
所有产品 - woocommerce/all-products
以网格布局显示您商店中的产品。
- Name: woocommerce/all-products
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), interactivity (
clientNavigation),html,inserter,multiple - Attributes: alignButtons, columns, contentVisibility, isPreview, layoutConfig, orderby, rows
按照属性的产品 - woocommerce/products-by-attribute
显示带有所选属性的产品网格。
- Name: woocommerce/products-by-attribute
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: align (full, wide), interactivity (
clientNavigation),html,inserter - Attributes: alignButtons, attrOperator, attributes, columns, contentVisibility, isPreview, orderby, rows, stockStatus
评分筛选控件 - woocommerce/rating-filter
允许客户根据评分筛选产品网格。
- Name: woocommerce/rating-filter
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (background, button, text), interactivity (
clientNavigation),html,inserter,lock,multiple - Attributes: className, displayStyle, isPreview, selectType, showCounts, showFilterButton
所有评论 - woocommerce/all-reviews
显示所有产品的评论列表。
- Name: woocommerce/all-reviews
- Category: woocommerce
- Ancestor:
- Parent:
- Supports: color (text,
background), interactivity (clientNavigation), typography (fontSize),html - Attributes:
按分类显示评论 - woocommerce/reviews-by-category
显示来自特定分类的商品评论。
- Name: woocommerce/reviews-by-category
- 分类: woocommerce
- Ancestor:
- Parent:
- Supports: 颜色 (文本,
背景), 交互性 (clientNavigation), 排版 (fontSize),html - 属性:
按产品显示评论 - woocommerce/reviews-by-product
显示您产品的评论。
- Name: woocommerce/reviews-by-product
- 分类: woocommerce
- Ancestor:
- Parent:
- Supports: 颜色 (文本,
背景), 交互性 (clientNavigation), 排版 (fontSize),html - 属性:
单个产品 - woocommerce/single-product
显示您选择的单个产品,并完全控制其显示方式。
- Name: woocommerce/single-product
- 分类: woocommerce
- Ancestor:
- Parent:
- Supports: 对齐 (full, wide), 交互性
- 属性: isPreview, productId
库存状态筛选控件 - woocommerce/stock-filter
允许客户根据库存状态筛选商品列表。
- Name: woocommerce/stock-filter
- 分类: woocommerce
- Ancestor:
- Parent:
- Supports: 颜色 (背景, 按钮, 文本), 交互性 (
clientNavigation),html,插入器,锁定,多选 - 属性: className, displayStyle, headingLevel, isPreview, selectType, showCounts, showFilterButton
商店通知 - woocommerce/store-notices
显示由 WooCommerce 或扩展程序生成的面向购物者的通知。
- Name: woocommerce/store-notices
- 分类: woocommerce
- Ancestor:
- Parent:
- Supports: 对齐 (full, wide), 交互性 (clientNavigation),
多选 - 属性: align
处理脚本、样式和数据
问题
您是一位扩展开发者,为了允许用户在客户端与您的扩展进行交互,您编写了一些 CSS 和 JavaScript 代码,希望这些代码能够包含在网页中。 您的 JavaScript 代码还依赖于一些服务器端数据,并且您希望这些数据能够被您的脚本访问。
解决方案
您可以使用 IntegrationRegistry 来注册一个 IntegrationInterface。 这将是一个类,用于处理脚本、样式和数据的加载。 您可以为每个块(迷你购物车、购物车和结账)使用不同的 IntegrationInterface,也可以使用同一个,这完全取决于您的用例。
您应该使用以下钩子:woocommerce_blocks_mini-cart_block_registration、woocommerce_blocks_cart_block_registration 和 woocommerce_blocks_checkout_block_registration。 这些钩子会将 IntegrationRegistry 的实例传递给回调函数。
然后,您可以使用此对象的 register 方法来注册您的 IntegrationInterface。
IntegrationInterface 方法
首先,我们需要创建一个集成类,即我们的 IntegrationInterface。 这将是一个实现 WooCommerce Blocks 接口的类,该接口名为 IntegrationInterface。
在本部分中,我们将逐步介绍接口的成员,并讨论它们的用途。
get_name()
这是 IntegrationInterface 为您的集成提供命名空间的方式。 在这里选择的名称应与您的扩展唯一。 此方法应返回一个字符串。
initialize()
您应该在此处放置任何设置或初始化的代码。 例如,您可以在此处注册您的扩展所需的脚本和样式。 此方法不应返回任何值。
get_script_handles()
在此处放置您希望在前端客户端加载的任何脚本的句柄。 此方法应返回一个字符串数组。
get_editor_script_handles()
在此处放置您希望在编辑器客户端加载的任何脚本的句柄。 此方法应返回一个字符串数组。
get_script_data()
您可以在此处设置希望在前端脚本中可用的值。 此方法应返回一个关联数组,其键将用于通过 JavaScript 函数 getSetting 获取数据。
此数组的键和值都应该是可序列化的。
使用示例
假设我们是扩展的作者:WooCommerce Example Plugin。我们希望在 Mini-Cart、Cart 或 Checkout 块被使用时,在前端注册脚本、样式和数据。
我们还希望从服务器端函数获取一些数据,并在前端脚本中使用。
您会注意到,在下面的示例中,我们引用了 /build/index.asset.php 文件。该文件由 DependencyExtractionWebpackPlugin 创建,它创建一个 PHP 文件,用于映射客户端脚本的依赖项,以便它们可以添加到 wp_register_script 的 dependencies 数组中。
让我们创建我们的 IntegrationInterface。
<?php
use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;
/**
* Class for integrating with WooCommerce Blocks
*/
class WooCommerce_Example_Plugin_Integration implements IntegrationInterface {
/**
* The name of the integration.
*
* @return string
*/
public function get_name() {
return 'woocommerce-example-plugin';
}
/**
* When called invokes any initialization/setup for the integration.
*/
public function initialize() {
$script_path = '/build/index.js';
$style_path = '/build/style-index.css';
/**
* The assets linked below should be a path to a file, for the sake of brevity
* we will assume \WooCommerce_Example_Plugin_Assets::$plugin_file is a valid file path
*/
$script_url = plugins_url( $script_path, \WooCommerce_Example_Plugin_Assets::$plugin_file );
$style_url = plugins_url( $style_path, \WooCommerce_Example_Plugin_Assets::$plugin_file );
$script_asset_path = dirname( \WooCommerce_Example_Plugin_Assets::$plugin_file ) . '/build/index.asset.php';
$script_asset = file_exists( $script_asset_path )
? require $script_asset_path
: array(
'dependencies' => array(),
'version' => $this->get_file_version( $script_path ),
);
wp_enqueue_style(
'wc-blocks-integration',
$style_url,
[],
$this->get_file_version( $style_path )
);
wp_register_script(
'wc-blocks-integration',
$script_url,
$script_asset['dependencies'],
$script_asset['version'],
true
);
wp_set_script_translations(
'wc-blocks-integration',
'woocommerce-example-plugin',
dirname( \WooCommerce_Example_Plugin_Assets::$plugin_file ) . '/languages'
);
}
/**
* Returns an array of script handles to enqueue in the frontend context.
*
* @return string[]
*/
public function get_script_handles() {
return array( 'wc-blocks-integration' );
}
/**
* Returns an array of script handles to enqueue in the editor context.
*
* @return string[]
*/
public function get_editor_script_handles() {
return array( 'wc-blocks-integration' );
}
/** * 一个包含键值对的数据数组,这些数据在客户端提供给块。 * * @return array */ public function get_script_data() { $woocommerce_example_plugin_data = some_expensive_serverside_function(); return [ 'expensive_data_calculation' => $woocommerce_example_plugin_data ]; }
/**
* 获取文件修改时间,作为缓存清除标志,如果我们在开发模式下。
*
* @param string $file 文件的本地路径。
* @return string 用于指定文件的缓存清除值。
*/
protected function get_file_version( $file ) {
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( $file ) ) {
return filemtime( $file );
}
// 就像上面所说,我们假设 WooCommerce_Example_Plugin_Assets::VERSION 解析为我们的扩展使用的某个版本号。
return \WooCommerce_Example_Plugin_Assets::VERSION;
}
}
如上所述,我们需要将我们的 `IntegrationInterface` 与 WooCommerce Blocks 注册,因为我们希望在 Mini-Cart、Cart 或 Checkout 被使用时,我们的脚本被包含。因此,我们需要注册三个操作的回调函数。
```php
add_action(
'woocommerce_blocks_mini-cart_block_registration',
function( $integration_registry ) {
$integration_registry->register( new WooCommerce_Example_Plugin_Integration() );
}
);
add_action(
'woocommerce_blocks_cart_block_registration',
function( $integration_registry ) {
$integration_registry->register( new WooCommerce_Example_Plugin_Integration() );
}
);
add_action(
'woocommerce_blocks_checkout_block_registration',
function( $integration_registry ) {
$integration_registry->register( new WooCommerce_Example_Plugin_Integration() );
}
);
现在,当我们加载包含任何一个块的网页时,我们应该看到在 initialize 中注册的脚本被加载!
获取 get_script_data 中添加的数据
我们在 get_script_data 方法的 界面 中,将一些 数据 与扩展关联起来,我们需要知道如何获取这些 数据!
在 @woocommerce/settings 包 中,有一个名为 getSetting 的 方法,您可以导入它。 此 方法 接受一个 字符串。 包含在 get_script_data 中添加的 数据 的 设置 名称,是您的 集成 的名称(即 get_name 返回的 价值),并在其后加上 _data。 在我们的 例子 中,它将是:woocommerce-example-plugin_data。
这里返回的 价值 是一个普通的 JavaScript 对象,其键由 get_script_data 返回的数组中的键组成,这些 值 将被序列化。
客户端和服务器之间的数据流概述
在 WooCommerce 购物车和结账模块中,服务器是关键事务性数据的权威来源。这包括:
- 购物车商品详情(商品、数量和价格)
- 购物车总额(例如,税费、费用、小计)
- 客户信息(收货地址和账单地址,以及其他客户数据)
- 使用 Additional Checkout Fields API 添加的附加字段也保存在服务器端。
- 配送方式和运费
- 其他购物车详情,例如已应用的优惠券
此类数据必须保存在服务器端,以确保不同用户会话和设备上的准确性、一致性和可靠性。 瞬态的 UI 状态——例如,临时验证状态,或 UI 相关的交互,如展开/折叠的部分,应保留在客户端,并且除非需要跨页面加载维护特定状态,或者该状态对用户的结账过程至关重要,否则不应自动保存在服务器上。
您可能希望将数据从服务器传输到客户端,反之亦然。本文档将概述购物车/结账模块中的一般概念和数据流,并提供链接或指导,以帮助您了解一些常见用例。
数据存储在哪里?
所有与购物车、客户和订单相关的数据都存储在服务器上,要么存储在数据库中,要么存储在客户的会话中。当数据发送到客户端时,它存储在 @wordpress/data 数据存储中。
如何将服务器端 (PHP) 数据导入到客户端 (JavaScript) 以及反之
由于服务器是权威来源,因此客户端的所有数据最终都应该传输到服务器,如果需要将其与订单一起持久化。
此外,还存在一种情况,即您的客户端需要只能在服务器端派生的数据,例如在 WooCommerce 设置仪表盘中设置的配置选项,或者来自外部服务的数据(例如,快递费率或支付 API)。
服务器 (PHP) 到 客户端 (JavaScript)
有两种方法可以将数据从服务器传输到客户端,具体取决于数据是静态的还是动态的。
静态数据
静态数据不太可能因为用户的操作而发生变化,例如来自 WooCommerce 设置仪表盘的某个选项。 将这些数据传递给客户端的推荐方法是使用 AssetDataRegistry。
当数据添加到此处时,它会被序列化并发送到客户端,并在页面加载时生效。 它不会因为用户的操作而改变,例如将商品添加到购物车或更改地址。
可以将键/值对添加到注册表中,如下所示:
add_action(
'woocommerce_blocks_loaded',
function() {
$asset_data_registry = \Automattic\WooCommerce\Blocks\Package::container()->get( \Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry::class );
$asset_data_registry->add( 'namespace/value', 'this is a custom value' );
}
);
如果存在重复的键,则不会被覆盖。 使用唯一的标识符非常重要,建议使用 namespace/value 以确保键的唯一性。
要在客户端获取这些数据,请使用 wc.wcSettings.getSetting,如下所示:
const myCustomValue = wc.wcSettings.getSetting(
'namespace/value',
'Fallback value.'
);
动态数据
动态数据是指可能响应用户操作而发生变化的数据,例如更改位置或购物车中的商品。 在这种情况下,您需要将这些数据添加到购物车 API 响应中。 购物车响应在用户购物过程中的许多路由中都会发送,并且几乎每个由购物车/结账模块触发的 API 响应都包含它。
要添加数据,您需要扩展 API 响应。 请参阅 在 Store API 中暴露您的数据。
客户端 (JavaScript) 到 服务器 (PHP)
从客户端获取数据到服务器可以通过三种不同的方式实现:
结账字段更新
当用户更新结账字段时,数据会立即发送到服务器。 对于附加字段,这些数据通过 PUT 请求发送到 /checkout 接口。 对于地址字段,这些数据通过 POST 请求发送到 cart/update-customer 接口(通过批量)。 这两种方式都会返回一个更新后的购物车,然后将其应用到客户端,并更新总价。
附加到 Store API 请求
这对于不需要服务器立即响应的情况非常有用,例如,如果您在结账流程中添加了一个新块,并且该块包含一个需要与订单一起保存的表单字段。如果该表单字段只需要保存,而不需要更新购物车中的任何其他值,则应将数据与结账请求一起发送。 将包含自定义字段的自定义内部块添加到 WooCommerce 结账块 文档提供了一个使用 setExtensionData 以及扩展 Store API 以在现有请求中接收您的数据的工作示例。
使用 extensionCartUpdate 按需发送数据
您可能希望立即将数据发送到服务器,而不是等待 Store API 请求。如果数据可能更新购物车,例如添加费用、更改可用的配送方式或更改税率,则可能需要这样做。
使用 Store API 按需更新购物车 文档概述了如何执行此操作。
数据在购物车/结账块中何时发送/接收?
页面加载
在页面加载时,如果存在购物车或结账块,则购物车状态将与初始请求一起发送,并加载到客户端的 @wordpress/data 数据存储中。
在页面加载时,wc/store/cart 和 wc/store/checkout 数据存储会从服务器加载数据。wc/store/payment 数据存储部分数据来自服务器,但需要一些客户端处理才能完成,才能注册所有付款方式。
在结账表单中输入客户数据
当购物者在表单中输入数据时,数据会立即写入 wc/store/cart 数据存储,并且会调用一个防抖方法 `pushChanges。 该方法将客户数据发送到服务器,服务器将这些数据与客户信息关联并持久化。 完整的购物车数据作为响应返回,并且数据存储会使用这些数据进行更新。
需要注意的是,如果服务器上运行的代码修改了客户的地址信息,这些修改会反映在响应中。
例如,如果某个插件修改地址数据以确保所有城市名称都大写,并且购物者在城市字段中输入 "london",那么当数据返回给客户端时,文本会变为 "London",并且输入字段会更新。
在购物者与表单交互时修改表单字段会造成不好的用户体验,因此,建议不要在用户与表单交互时进行这些修改,而是在服务器上处理结账操作时进行修改。
添加优惠券
当购物者展开优惠券表单时,状态会存储在本地。 这种类型的数据不会发送到服务器。 当购物者按下“应用”按钮时,会发送添加优惠券的请求。 会发送一个 Store API 请求,并返回一个新的购物车,然后将该购物车应用。
更改配送方式
当购物者更改配送方式时,会发送一个 Store API 请求,并返回一个新的购物车,然后将该购物车应用。
更改支付方式
当购物者更改支付方式时,不会自动发送 Store API 请求到服务器。 如果需要在支付方式更改时更新服务器,并且在订单提交之前,正确的做法是使用 [cartExtensionUpdate](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md)。
添加/编辑订单备注
添加或编辑订单备注时,这些备注会存储在客户端本地,只有当购物者提交结账表单时,才会将这些备注发送到服务器。
购物车
上面“结账”部分中列出的项目也适用于“购物车”模块(除了更改支付方式之外,购物者在“购物车”模块中无法选择支付方式,除非是快速支付方式,其行为方式不同,并且完全在客户端实现)。
更改商品数量、添加或移除商品
当购物者更新商品的数量、从购物车中移除商品,或添加商品(例如,从“购物车交叉销售”模块中添加商品)时,会发送一个 Store API 请求。 客户端本地的购物车会使用响应进行更新。
使用配送计算器
它的行为方式与“结账”模块中的地址表单相同,但是,配送计算器中的地址只有在邮编有效,并且所有必填字段都已填写时,才会发送到服务器。
Slot 和 Fill
问题
您向 Store API 添加了自定义数据。您使用 结账过滤器 修改了多个字符串。现在,您想在购物车和结账的特定位置渲染您自己的组件。
解决方案
Slot 和 Fill 是两个组件,它们提供了在购物车和结账的预定义位置渲染您自己的 HTML 的可能性。您的组件将访问上下文数据,并在需要时自动重新渲染。
Slot 是购物车和结账中可以渲染无限数量的外部组件的位置。
Fill 是第三方开发者提供的组件,用于在 Slot 中渲染。
Slot 和 Fill 使用 WordPress 的 API,您可以在 Slot 和 Fill 文档 中了解更多关于它们的工作原理。
基本用法
ExperimentalOrderMeta 是一个 Fill 组件,它将在购物车和结账块中的“订单摘要”部分下方渲染。
ExperimentalOrderMeta 会自动将 props 传递给其顶层子组件:
cart,包含购物车数据extensions,包含在wc/store/cart端点中通过ExtendSchema::class注册的数据context,等于 Fill 组件所在的 Block 的名称:woocommerce/cart或woocommerce/checkout
const { registerPlugin } = wp.plugins;
const { ExperimentalOrderMeta } = wc.blocksCheckout;
const MyCustomComponent = ( { cart, extensions } ) => {
return <div className="my-component">Hello WooCommerce</div>;
};
const render = () => {
return (
<ExperimentalOrderMeta>
<MyCustomComponent />
</ExperimentalOrderMeta>
);
};
registerPlugin( 'my-plugin-namespace', {
render,
scope: 'woocommerce-checkout',
} );
registerPlugin
在上面的示例中,我们正在使用 registerPlugin。这个插件将接收我们的组件并渲染它,但它不会使其可见。SlotFill 部分负责实际将其显示在正确的位置。
您使用 registerPlugin 来提供您的插件命名空间、您的组件 render 以及您的 registerPlugin 的作用域。作用域的值始终应该是 woocommerce-checkout。
需求
要使此功能正常工作,您的脚本必须在购物车和结账之后被加载。您可以参考 集成界面 文档来了解如何加载您的脚本。
购物车商店 (`wc/store/cart`)
💡 购物车商店和结账商店有什么区别?
购物车商店 (
wc/store/cart) 用于管理和检索关于购物车的的数据,包括商品、客户数据以及与优惠券相关的交互。结账商店 (
wc/store/checkout) 用于管理和检索与结账过程相关的数据,包括客户 ID、订单 ID 和结账状态。
概述
购物车商店提供了一组选择器和方法,用于管理和检索 WooCommerce Blocks 中与购物车相关的数据。它提供了从获取购物车详情到管理客户交互的功能,例如应用优惠券或更新配送信息。
使用方法
要使用此商店,您需要在任何引用它的模块中导入 cartStore StoreDescriptor。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部,您可以通过以下方式导入 StoreDescriptor:
const { cartStore } = window.wc.wcBlocksData;
操作
setCartData
此操作用于在商店中设置购物车数据。
参数
- cartData
object: 当前的购物车数据,包含以下键:- coupons
array: 购物车中的优惠券项。 - shippingRates
array: 购物车中的配送费率(参见getShippingRates选择器)。 - shippingAddress
object: 配送地址(参见getCustomerData选择器)。 - billingAddress
object: 账单地址(参见getCustomerData选择器)。 - items
array: 购物车中的商品。 - itemsCount
number: 购物车中商品的总数量。 - itemsWeight
number: 购物车中商品的总重量。 - crossSells
array: 推荐商品。 - needsPayment
boolean: 购物车是否需要支付。 - needsShipping
boolean: 购物车是否需要配送。 - hasCalculatedShipping
boolean: 购物车是否已计算出配送费。 - fees
array: 购物车中的费用。 - totals
object: 购物车中的总计(参见getCartTotals选择器)。 - errors
array: 购物车中的错误(参见getCartErrors选择器)。 - paymentRequirements
object: 购物车中的支付要求。 - extensions
object: 扩展数据。
- coupons
示例
const { dispatch } = useDispatch( cartStore );
dispatch( setCartData( newCartData ) );
setErrorData
此操作用于在商店中设置错误数据。
参数
- errorData
object: 需要在商店中设置的错误数据。- code
string: 错误代码。 - message
string: 错误消息。 - data
object: 额外的错误数据。 这是一个可选的对象,包含以下键:- status
number: 错误状态。 - params
string: 错误参数。 - message
string: 错误消息。 - cart
object: 购物车数据。 这是一个可选的对象,包含以下键:- coupons
array: 购物车中的优惠券项。 - shippingRates
array: 购物车配送费率(参见getShippingRates选择器)。 - shippingAddress
object: 配送地址(参见getCustomerData选择器)。 - billingAddress
object: 账单地址(参见getCustomerData选择器)。 - items
array: 购物车中的商品项。 - itemsCount
number: 购物车中商品的总数量。 - itemsWeight
number: 购物车中商品的总重量。 - crossSells
array: 推荐商品项。 - needsPayment
boolean: 购物车是否需要支付。 - needsShipping
boolean: 购物车是否需要配送。 - hasCalculatedShipping
boolean: 购物车是否已计算出配送费。 - fees
array: 购物车费用。 - totals
object: 购物车总额(参见getCartTotals选择器)。 - errors
array: 购物车错误(参见getCartErrors选择器)。 - paymentRequirements
object: 购物车支付要求。 - extensions
object: 扩展数据。
- coupons
- status
- code
示例
const { dispatch } = useDispatch( cartStore );
dispatch( setErrorData( newErrorData ) );
receiveCartContents
此操作返回一个操作对象,用于使用提供的购物车数据更新商店。 它省略了客户的地址,以便仅接收购物车项和总额的更新。
参数
- cartContents
object: 购物车内容的 API 响应。- coupons
array: 购物车中的优惠券项目。 - shippingRates
array: 购物车的配送费率(参见getShippingRates选择器)。 - shippingAddress
object: 配送地址(参见getCustomerData选择器)。 - billingAddress
object: 账单地址(参见getCustomerData选择器)。 - items
array: 购物车中的项目。 - itemsCount
number: 购物车中项目的总数。 - itemsWeight
number: 购物车中项目的总重量。 - crossSells
array: 推荐商品。 - needsPayment
boolean: 如果购物车需要支付。 - needsShipping
boolean: 如果购物车需要配送。 - hasCalculatedShipping
boolean: 如果购物车已计算出配送费。 - fees
array: 购物车中的费用。 - totals
object: 购物车总额(参见getCartTotals选择器)。 - errors
array: 购物车中的错误(参见getCartErrors选择器)。 - paymentRequirements
object: 购物车支付要求。 - extensions
object: 扩展数据。
- coupons
返回值
object: 包含以下键的动作对象:- type
string: 动作类型。 - cartContents
object: 购物车内容,包含以下键:- coupons
array: 购物车中的优惠券项目。 - shippingRates
array: 购物车的配送费率(参见getShippingRates选择器)。 - items
array: 购物车中的项目。 - itemsCount
number: 购物车中项目的总数。 - itemsWeight
number: 购物车中项目的总重量。 - crossSells
array: 推荐商品。 - needsPayment
boolean: 如果购物车需要支付。 - needsShipping
boolean: 如果购物车需要配送。 - hasCalculatedShipping
boolean: 如果购物车已计算出配送费。 - fees
array: 购物车中的费用。 - totals
object: 购物车总额(参见getCartTotals选择器)。 - errors
array: 购物车中的错误(参见getCartErrors选择器)。 - paymentRequirements
object: 购物车支付要求。 - extensions
object: 扩展数据。
- coupons
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( receiveCartContents( newCartContents ) );
receiveApplyingCoupon
此动作返回一个动作对象,用于跟踪何时应用优惠券。
参数
- couponCode
string: 正在应用的优惠券代码。
返回值
object: 包含以下键的动作对象:- type
string: 动作类型。 - couponCode
string: 正在应用的优惠券代码。
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( receiveApplyingCoupon( couponCode ) );
receiveRemovingCoupon
此操作返回一个操作对象,用于跟踪优惠券的移除状态。
参数
- couponCode
string: 要移除的优惠券的代码。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - couponCode
string: 要移除的优惠券的代码。
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( receiveRemovingCoupon( couponCode ) );
receiveCartItem
此操作用于更新购物车中的特定项目。
参数
- cartResponseItem
object: 购物车响应对象,包含以下键:- cartItem
object: 购物车项目(请参阅getCartItem选择器)。
- cartItem
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - cartItem
object: 购物车项目(请参阅getCartItem选择器)。
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( receiveCartItem( CartResponseItem ) );
itemIsPendingQuantity
此操作返回一个操作对象,用于指示购物车中指定项目的数量是否正在更新。
参数
- cartItemKey
string: 购物车项目的键。 - isPending
boolean(默认值:true): 指示购物车项目数量是否正在更新。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - cartItemKey
string: 购物车项目的键。 - isPending
boolean: 指示购物车项目数量是否正在更新。
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( itemIsPendingQuantity( cartItemKey, isPending ) );
itemIsPendingDelete
此操作返回一个操作对象,用于指示购物车中的指定项目是否正在被删除。
参数
- cartItemKey
string: 购物车项目的键。 - isPending
boolean(默认值:true): 指示购物车项目是否正在被删除。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - cartItemKey
string: 购物车项目的键。 - isPending
boolean: 指示购物车项目是否正在被删除。
- type
示例
const { dispatch } = useDispatch( cartStore );
dispatch( itemIsPendingDelete( cartItemKey, isPending ) );
setIsCartDataStale
此操作返回一个操作对象,用于指示购物车数据是否已过期。
参数
- isCartDataStale
boolean(默认值:true): 用于标记购物车数据是否过期的标志;如果lastCartUpdate时间戳比wcSettings中的时间戳更早,则为true。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - isCartDataStale
boolean: 用于标记购物车数据是否过期的标志;如果lastCartUpdate时间戳比wcSettings中的时间戳更早,则为true。
- type
Example
const { dispatch } = useDispatch( cartStore );
dispatch( setIsCartDataStale( isCartDataStale ) );
updatingCustomerData
此操作返回一个操作对象,用于指示客户数据(账单和/或配送地址)是否正在更新。
参数
- isResolving
boolean: 指示客户数据是否正在更新。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - isResolving
boolean: 指示客户数据是否正在更新。
- type
Example
const { dispatch } = useDispatch( cartStore );
dispatch( updatingCustomerData( isResolving ) );
shippingRatesBeingSelected
此操作返回一个操作对象,用于指示是否正在选择配送费率。
参数
- isResolving
boolean: 如果正在选择配送费率,则为true。
返回值
object: 包含以下键的操作对象:- type
string: 操作类型。 - isResolving
boolean: 如果正在选择配送费率,则为true。
- type
Example
const { dispatch } = useDispatch( cartStore );
dispatch( shippingRatesBeingSelected( isResolving ) );
applyExtensionCartUpdate
此操作用于向 /cart/extensions 端点发送 POST 请求,并将扩展提供的相关数据一同发送。
参数
- args
object: 请求的参数,包含以下键:- extensionId
string: 扩展 ID。 - data
object: 要发送到端点的的数据,包含以下键:- key
string: 扩展的键。 - value
string: 扩展的数值。
- key
- overwriteDirtyCustomerData
boolean: 指示是否使用服务器返回的数据覆盖客户端的客户数据,即使该数据尚未推送到服务器。
- extensionId
Example
const { dispatch } = useDispatch( cartStore );
dispatch( applyExtensionCartUpdate( args ) );
applyCoupon
此操作用于将优惠券应用于购物车。
参数
- couponCode
string: 要应用的优惠券代码。
Example
const { dispatch } = useDispatch( cartStore );
dispatch( applyCoupon( couponCode ) );
removeCoupon
此操作用于从购物车中移除优惠券。
参数
- couponCode
string: 要移除的优惠券代码。
Example
const { dispatch } = useDispatch( cartStore );
dispatch( removeCoupon( couponCode ) );
addItemToCart
此操作用于将商品添加到购物车。
参数
- productId
number: 要添加到购物车的 产品 ID。 - quantity
number(默认值:1): 要添加的商品数量。
Example
const { dispatch } = useDispatch( cartStore );
dispatch( addItemToCart( productId, quantity ) );
removeItemFromCart
此操作用于从购物车中移除商品。
参数
- cartItemKey
string: 需要更新的购物车项。
示例
const { dispatch } = useDispatch( cartStore );
dispatch( removeItemFromCart( cartItemKey ) );
changeCartItemQuantity
此操作用于更改购物车中某个商品的数量。
参数
- cartItemKey
string: 需要更新的购物车项。 - quantity
number: 商品的数量。
示例
const { dispatch } = useDispatch( cartStore );
dispatch( changeCartItemQuantity( cartItemKey, quantity ) );
selectShippingRate
此操作用于选择购物车中的配送方式。
参数
- rateId
string: 要选择的配送方式的 ID。 - packageId
number | string(默认:null): 将在选定的配送方式中选择的包裹的键。
示例
const { dispatch } = useDispatch( cartStore );
dispatch( selectShippingRate( rateId, packageId ) );
setBillingAddress
此操作用于在本地设置购物车的账单地址,而不是 updateCustomerData,后者会将数据发送到服务器。
参数
- billingAddress
object: 需要设置的账单地址。键如下:- first_name
string: 名。 - last_name
string: 姓氏。 - company
string: 公司名称。 - address_1
string: 地址行 1。 - address_2
string: 地址行 2。 - city
string: 城市名称。 - state
string: 州/省名称。 - postcode
string: 邮政编码。 - country
string: 国家名称。
- first_name
示例
const { dispatch } = useDispatch( cartStore );
dispatch( setBillingAddress( billingAddress ) );
setShippingAddress
此操作用于在本地设置购物车的配送地址,而不是 updateCustomerData,后者会将数据发送到服务器。
参数
- shippingAddress
object: 需要设置的配送地址。键如下:- first_name
string: 名。 - last_name
string: 姓氏。 - company
string: 公司名称。 - address_1
string: 地址行 1。 - address_2
string: 地址行 2。 - city
string: 城市名称。 - state
string: 州/省名称。 - postcode
string: 邮政编码。 - country
string: 国家名称。
- first_name
示例
const { dispatch } = useDispatch( cartStore );
dispatch( setShippingAddress( shippingAddress ) );
updateCustomerData
此操作用于更新客户的配送和/或账单地址,并返回一个更新后的购物车。
参数
- customerData
object: 客户的账单和配送地址。键如下:- shippingAddress
object: 配送地址,包含以下键:- first_name
string: 名。 - last_name
string: 姓氏。 - company
string: 公司名称。 - address_1
string: 地址行 1。 - address_2
string: 地址行 2。 - city
string: 城市名称。 - state
string: 州/省名称。 - postcode
string: 邮政编码。 - country
string: 国家名称。
- first_name
- billingAddress
object: 账单地址(与配送地址具有相同的键)。
- shippingAddress
editing: boolean(默认值:true): 如果正在编辑地址,则我们不会从响应中更新商店中的客户数据。
示例
const { dispatch } = useDispatch( cartStore );
dispatch( updateCustomerData( customerData, editing ) );
选择器
getCartData
返回来自状态的购物车数据。
返回值
object: 当前的购物车数据,包含以下键:- coupons
array: 购物车中的优惠券项。 - shippingRates
array: 购物车中的配送费率(参见getShippingRates选择器)。 - shippingAddress
object: 配送地址(参见getCustomerData选择器)。 - billingAddress
object: 账单地址。 - items
array: 购物车中的商品。 - itemsCount
number: 购物车中商品的总数量。 - itemsWeight
number: 购物车中商品的总重量。 - crossSells
array: 推荐商品。 - needsPayment
boolean: 购物车是否需要支付。 - needsShipping
boolean: 购物车是否需要配送。 - hasCalculatedShipping
boolean: 购物车是否已计算出配送费用。 - fees
array: 购物车中的费用。 - totals
object: 购物车总计(参见getCartTotals选择器)。 - errors
array: 购物车中的错误(参见getCartErrors选择器)。 - paymentRequirements
object: 购物车中的支付要求。 - extensions
object: 扩展数据。
- coupons
示例
const store = select( cartStore );
const cartData = store.getCartData();
getCustomerData
返回来自状态的配送和账单地址。
返回值
object: 当前的配送和账单地址,包含以下键:- shippingAddress
object: 配送地址,包含以下键:- first_name
string: 名。 - last_name
string: 姓氏。 - company
string: 公司名称。 - address_1
string: 地址行 1。 - address_2
string: 地址行 2。 - city
string: 城市名称。 - state
string: 州/省名称。 - postcode
string: 邮政编码。 - country
string: 国家名称。
- first_name
- billingAddress
object: 账单地址(包含与配送地址相同的键)。
- shippingAddress
示例
const store = select( cartStore );
const customerData = store.getCustomerData();
getShippingRates
从状态获取配送费率。
返回值
array: 配送费率。键如下:- id
string: 配送费率 ID。 - label
string: 配送费率标签。 - cost
string: 配送费率费用。 - package_id
number: 配送费率包裹 ID。 - meta_data
array: 配送费率元数据。键如下:- id
number: 配送费率元数据 ID。 - key
string: 配送费率元数据键。 - value
string: 配送费率元数据值。
- id
- taxes
array: 配送费率税费。
- id
示例
const store = select( cartStore );
const shippingRates = store.getShippingRates();
getNeedsShipping
查询购物车是否需要配送。
返回值
boolean: 如果购物车需要配送,则返回true。
示例
const store = select( cartStore );
const needsShipping = store.getNeedsShipping();
getHasCalculatedShipping
查询购物车配送费是否已计算。
返回值
boolean: 如果配送费已计算,则返回true。
示例
const store = select( cartStore );
const hasCalculatedShipping = store.getHasCalculatedShipping();
getCartTotals
从状态返回购物车总计。
返回值
object: 当前购物车总计信息,包含以下键:_total_items_:string: 购物车中所有项目的总价,不包含折扣、税费或配送费。_total_items_tax_:string: 所有项目之前的税费总额。_total_fees_:string: 总交易手续费。_total_fees_tax_:string: 总交易手续费的税费。_total_discount_:string: 应用于购物车的总折扣。_total_discount_tax_:string: 应用于总折扣金额的税费。_total_shipping_:string: 总配送费用。_total_shipping_tax_:string: 应用于总配送费用的税费。_total_tax_:string: 应用于购物车的总税费。_total_price_:string: 购物车总价,包含折扣、税费或配送费。_tax_lines_:arrayof object: 税费明细,包含name(名称)、price(价格)和rate(税率)。_currency_code_:string: 购物车的货币代码。_currency_symbol_:string: 购物车的货币符号。_currency_minor_unit_:integer: 购物车的货币最小单位。_currency_decimal_separator_:string: 购物车的货币小数分隔符。_currency_thousand_separator_:string: 购物车的货币千位分隔符。_currency_prefix_:string: 购物车的货币前缀。_currency_suffix_:string: 购物车的货币后缀。
示例
const store = select( cartStore );
const cartTotals = store.getCartTotals();
getCartMeta
从状态中获取购物车元数据。
返回值
object: 当前购物车元数据,包含以下键:_updatingCustomerData_:boolean: 如果正在更新客户数据(账单和/或配送地址)。_updatingSelectedRate_:boolean: 如果正在更新选定的税率。_isCartDataStale_:boolean: 如果购物车数据已过期。_applyingCoupon_:string: 正在应用的优惠券代码。_removingCoupon_:string: 正在移除的优惠券代码。
示例
const store = select( cartStore );
const cartMeta = store.getCartMeta();
getCartErrors
如果购物车从 API 接收到面向用户的错误,则返回购物车错误。
返回值
array: 购物车错误,包含以下键:_code_:string: 错误代码。_message_:string: 错误消息。_data_:object: API 响应数据。
示例
const store = select( cartStore );
const cartErrors = store.getCartErrors();
isApplyingCoupon
查询是否正在应用优惠券。
返回值
boolean: 如果正在应用优惠券,则返回true。
示例
const store = select( cartStore );
const isApplyingCoupon = store.isApplyingCoupon();
isCartDataStale
查询购物车数据是否已过期。
返回值
boolean: 如果购物车数据已过期,则返回True。
例子
const store = select( cartStore );
const isCartDataStale = store.isCartDataStale();
getCouponBeingApplied
返回正在应用的优惠券代码。
返回值
string: 正在应用的优惠券代码。
例子
const store = select( cartStore );
const couponBeingApplied = store.getCouponBeingApplied();
isRemovingCoupon
查询是否正在移除优惠券。
返回值
boolean: 如果正在移除优惠券,则返回True。
例子
const store = select( cartStore );
const isRemovingCoupon = store.isRemovingCoupon();
getCouponBeingRemoved
返回正在移除的优惠券代码。
返回值
string: 正在移除的优惠券代码。
例子
const store = select( cartStore );
const couponBeingRemoved = store.getCouponBeingRemoved();
getCartItem( cartItemKey )
从状态中返回一个购物车项目。
参数
- cartItemKey
string: 购物车项目的关键字。
返回结果
object: 购物车项目,包含以下键:- key
string: 购物车项目的键。 - id
number: 购物车项目ID。 - catalog_visibility
string: 目录可见性。 - quantity_limits
object: 数量限制。 - name
string: 购物车项目名称。 - summary
string: 购物车项目摘要。 - short_description
string: 购物车项目简短描述。 - description
string: 购物车项目描述。 - sku
string: 购物车项目SKU。 - low_stock_remaining
nullornumber: 剩余库存。 - backorders_allowed
boolean: 指示是否允许延期交货。 - show_backorder_badge
boolean: 指示是否应显示延期交货标识。 - sold_individually
boolean: 指示该项目是否单独销售。 - permalink
string: 购物车项目的固定链接。 - images
array: 购物车项目图像。 - variation
array: 购物车项目变体。 - prices
object: 购物车项目价格,包含以下键:- currency_code
string: 货币代码。 - currency_symbol
string: 货币符号。 - currency_minor_unit
number: 货币小数单位。 - currency_decimal_separator
string: 货币小数分隔符。 - currency_thousand_separator
string: 货币千位分隔符。 - currency_prefix
string: 货币前缀。 - currency_suffix
string: 货币后缀。 - price
string: 购物车项目价格。 - regular_price
string: 购物车项目常规价格。 - sale_price
string: 购物车项目促销价格。 - price_range
string: 购物车项目价格范围。
- currency_code
- totals
object: 购物车项目总计,包含以下键:- currency_code
string: 货币代码。 - currency_symbol
string: 货币符号。 - currency_minor_unit
number: 货币小数单位。 - currency_decimal_separator
string: 货币小数分隔符。 - currency_thousand_separator
string: 货币千位分隔符。 - currency_prefix
string: 货币前缀。 - currency_suffix
string: 货币后缀。 - line_subtotal
string: 购物车项目小计。 - line_subtotal_tax
string: 购物车项目小计税额。 - line_total
string: 购物车项目总计。 - line_total_tax
string: 购物车项目总计税额。
- currency_code
- key
示例
const store = select( cartStore );
const cartItem = store.getCartItem( cartItemKey );
isItemPendingQuantity( cartItemKey )
查询购物车项目是否处于待审数量状态。
参数
- cartItemKey
string: 购物车项目的键。
返回结果
boolean: 如果购物车项目处于待审数量状态,则返回true。
示例
const store = select( cartStore );
const isItemPendingQuantity = store.isItemPendingQuantity( cartItemKey );
isItemPendingDelete( cartItemKey )
查询购物车中的某个商品是否处于待审删除状态。
参数
- cartItemKey
字符串: 购物车商品键。
返回值
布尔值: 如果购物车中的商品处于待审删除状态,则返回true。
示例
const store = select( cartStore );
const isItemPendingDelete = store.isItemPendingDelete( cartItemKey );
isCustomerDataUpdating
查询客户数据是否正在更新。
返回值
布尔值: 如果客户数据正在更新,则返回true。
示例
const store = select( cartStore );
const isCustomerDataUpdating = store.isCustomerDataUpdating();
isAddressFieldsForShippingRatesUpdating
查询影响配送费率的配送地址字段是否正在更新。
默认情况下,Store API 认为以下配送字段对于配送费率计算至关重要:state、country、postcode 和 city。
返回值
布尔值: 如果影响配送费率的配送地址字段正在更新,则返回true。
示例
const store = select( cartStore );
const isAddressFieldsForShippingRatesUpdating = store.isAddressFieldsForShippingRatesUpdating();
hasPendingItemsOperations
查询是否存在任何待审的购物车操作(添加、更新数量或删除商品)。
返回值
布尔值: 如果存在待审的购物车操作(添加产品、更新数量或删除商品),则返回true。
示例
const store = select( cartStore );
const hasPendingItemsOperations = store.hasPendingItemsOperations();
isShippingRateBeingSelected
查询是否正在选择配送费率。
返回值
布尔值: 如果正在选择配送费率,则返回true。
示例
const store = select( cartStore );
const isShippingRateBeingSelected = store.isShippingRateBeingSelected();
getItemsPendingQuantityUpdate
获取正在更新数量的商品的商品键。
返回值
字符串[]: 包含正在更新数量的商品的商品键的数组。
示例
const store = select( cartStore );
const itemsPendingQuantityUpdate = store.getItemsPendingQuantityUpdate();
getItemsPendingDelete
获取正在删除的商品的商品键。
返回值
字符串[]: 包含正在删除的商品的商品键的数组。
示例
const store = select( cartStore );
const itemsPendingDelete = store.getItemsPendingDelete();
结账商店 (`wc/store/checkout`)
💡 购物车商店和结账商店有什么区别?
购物车商店 (
wc/store/cart) 管理和检索关于购物车的的数据,包括商品、客户数据以及优惠券等交互。结账商店 (
wc/store/checkout) 管理和检索与结账过程相关的数据,包括客户 ID、订单 ID 和结账状态。
概述
结账商店提供了一组选择器,用于访问和管理结账过程中的数据。 这些选择器使开发者能够获取关键信息,例如客户信息、订单状态和其他与结账相关的的数据。
使用方法
要使用此商店,您需要在任何引用它的模块中导入 checkoutStore StoreDescriptor。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以通过以下方式导入 StoreDescriptor:
const { checkoutStore } = '@woocommerce/block-data'
如果未注册,您可以通过以下方式导入:
const { checkoutStore } = window.wc.wcBlocksData
选择器
getCustomerId
返回正在由结账块处理的客户的 WordPress 用户 ID。
返回值
number: 客户的 WordPress 用户 ID。
示例
const store = select( checkoutStore );
const customerId = store.getCustomerId();
getOrderId
返回正在由结账块处理的订单的 WooCommerce 订单 ID。
返回值
number: WooCommerce 订单 ID。
示例
const store = select( checkoutStore );
const orderId = store.getOrderId();
getOrderNotes
返回订单备注。
返回值
string: 订单备注。
示例
const store = select( checkoutStore );
const orderNotes = store.getOrderNotes();
getRedirectUrl
返回结账完成后要重定向到的 URL。
返回值
string: 要重定向到的 URL。
示例
const store = select( checkoutStore );
const redirectUrl = store.getRedirectUrl();
getExtensionData
返回由扩展注册的额外数据。
返回值
object: 由扩展注册的额外数据。
{
[ extensionNamespace ]: {
[ key ]: value,
},
}
示例
const store = select( checkoutStore );
const extensionData = store.getExtensionData();
getCheckoutStatus
返回结账过程的当前状态。
返回值
string: 结账过程的当前状态。 可能的值包括:pristine、before-processing、processing、after-processing、complete、idle。
示例
const store = select( checkoutStore );
const checkoutStatus = store.getCheckoutStatus();
getShouldCreateAccount
如果用户选择在下单时创建账户,则返回 true。
返回值
boolean: 如果用户选择在下单时创建账户,则返回 true。
示例
const store = select( checkoutStore );
const shouldCreateAccount = store.getShouldCreateAccount();
getUseShippingAsBilling
如果用户选择将收货地址作为账单地址,则返回 true。
返回值
boolean: 如果应该将收货地址用作账单地址,则返回 true。
示例
const store = select( checkoutStore );
const useShippingAsBilling = store.getUseShippingAsBilling();
getEditingBillingAddress
如果正在编辑账单地址,则返回 true。
返回值
boolean: 如果正在编辑账单地址,则返回 true。
示例
const store = select( checkoutStore );
const editingBillingAddress = store.getEditingBillingAddress();
getEditingShippingAddress
如果正在编辑收货地址,则返回 true。
返回值
boolean: 如果正在编辑收货地址,则返回 true。
示例
const store = select( checkoutStore );
const editingShippingAddress = store.getEditingShippingAddress();
hasError
如果发生错误,则返回 true,否则返回 false。
返回值
boolean: 如果发生错误,则返回 true。
示例
const store = select( checkoutStore );
const hasError = store.hasError();
hasOrder
如果已创建草稿订单,则返回 true,否则返回 false。
返回值
boolean: 如果已创建草稿订单,则返回 true。
示例
const store = select( checkoutStore );
const hasOrder = store.hasOrder();
isIdle
当结账状态为 IDLE 时,此标志为 true。 在加载阻止后,任何对结账状态的更改都会使结账处于此状态。 当在出现错误后可以重试购买时,结账也会处于此状态。
返回值
boolean: 如果结账已经有活动,但当前正在等待用户输入,则返回 true。
示例
const store = select( checkoutStore );
const isIdle = store.isIdle();
isBeforeProcessing
当结账状态为 BEFORE_PROCESSING 时,此标志为 true。 当用户提交结账以进行处理时,结账将处于此状态。
返回值
boolean: 如果订单即将被处理,则返回 true。
示例
const store = select( checkoutStore );
const isBeforeProcessing = store.isBeforeProcessing();
isProcessing
当结账状态为 PROCESSING 时,此标志为真。 结账会处于此状态,当所有在 BEFORE_PROCESSING 状态下触发的事件的观察者都已完成且没有发生错误时。 在此状态下,模块会向服务器发送请求,访问结账端点以处理订单。
返回值
boolean: 如果正在进行结账,则返回true。
示例
const store = select( checkoutStore );
const isProcessing = store.isProcessing();
isAfterProcessing
当结账状态为 AFTER_PROCESSING 时,此标志为真。 结账会在此状态下,当模块从服务器端处理请求接收到响应后。
返回值
boolean: 如果刚刚处理了一个订单,则返回true。
示例
const store = select( checkoutStore );
const isAfterProcessing = store.isAfterProcessing();
isComplete
当结账状态为 COMPLETE 时,此标志为真。 结账会在此状态下,当所有在 AFTER_PROCESSING 状态下触发的事件的观察者都已成功完成时。 当结账处于此状态时,购物者的浏览器将被重定向到 redirectUrl 的值(通常是 order-received 路由)。
返回值
boolean: 如果订单已完成,则返回true。
示例
const store = select( checkoutStore );
const isComplete = store.isComplete();
isCalculating
当订单的总价正在重新计算时,此标志为真。 有许多因素可能触发订单总价的重新计算:添加或移除优惠券、更新配送费率、选择配送费率等。 此标志汇总了所有可能发生的活动(包括可能影响总价计算的服务器请求)。 因此,您无需检查每个单独的状态,只需可靠地检查此布尔值是否为 true(正在计算)或 false(未计算)。
返回值
boolean: 如果正在进行更新任何值的请求,则返回true。
示例
const store = select( checkoutStore );
const isCalculating = store.isCalculating();
prefersCollection
如果客户选择自提订单,则返回 true,否则返回 false。
返回值
prefersCollectionboolean: 如果购物者选择自提订单,则返回true。
示例
const store = select( checkoutStore );
const prefersCollection = store.prefersCollection();
getRegisteredAutocompleteProviders
返回已注册的地址自动完成提供商 ID 列表。
返回值
- addressAutocompleteProviders
string[]: 注册的地址自动补全提供商 ID 列表。
示例
const store = select( checkoutStore );
const addressAutocompleteProviders = store.getRegisteredAutocompleteProviders();
getActiveAutocompleteProvider
返回给定地址类型的当前地址自动补全提供商。
参数
- type
'billing' | 'shipping': 地址类型。
返回值
- activeAddressAutocompleteProvider
string: 当前针对传入的地址类型,激活的地址自动补全提供商。
示例
const store = select( checkoutStore );
const activeBillingProvider = store.getActiveAutocompleteProvider( 'billing' );
操作
setPrefersCollection
将 prefersCollection 标志设置为 true 或 false。
参数
- prefersCollection
boolean: 如果用户希望自取订单,则为 true。
示例
const store = dispatch( checkoutStore );
store.setPrefersCollection( true );
setEditingBillingAddress
将账单地址设置为编辑状态或折叠状态。注意,如果地址存在无效的字段,则不会设置为折叠状态。
参数
- isEditing
boolean: 如果为 true,则将账单地址设置为编辑状态;如果为 false,则将其设置为折叠状态。
示例
const store = dispatch( checkoutStore );
store.setEditingBillingAddress( true );
setEditingShippingAddress
将配送地址设置为编辑状态或折叠状态。注意,如果地址存在无效的字段,则不会设置为折叠状态。
参数
- isEditing
boolean: 如果为 true,则将配送地址设置为编辑状态;如果为 false,则将其设置为折叠状态。
示例
const store = dispatch( checkoutStore );
store.setEditingShippingAddress( true );
addAddressAutocompleteProvider
添加一个地址自动补全提供商。
参数
- providerId
string: 提供商的名称。注意,提供商应使用wc.addressAutocomplete.registerAddressAutocompleteProvider进行注册。
示例
const store = dispatch( checkoutStore );
store.addAddressAutocompleteProvider( 'my-address-provider' );
setActiveAddressAutocompleteProvider
添加一个地址自动补全提供商。
参数
- providerId
string: 设置当前自动补全提供者的 ID。请注意,提供者需要通过wc.addressAutocomplete.registerAddressAutocompleteProvider进行注册。 - addressType
'billing' | 'shipping': 指定当前提供者适用于哪种地址类型。由于账单地址和配送地址可能位于不同的国家,因此每个国家可能需要不同的提供者。
示例
const store = dispatch( checkoutStore );
store.setActiveAddressAutocompleteProvider( 'my-address-provider', 'billing' );
Collections Store (`wc/store/collections`)
概述
Collections Store 允许在 WooCommerce Blocks 中检索与产品相关的集合。
使用方法
要使用此存储,您需要在任何引用它的模块中导入 COLLECTIONS_STORE_KEY。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以通过以下方式导入该键:
const { COLLECTIONS_STORE_KEY } = window.wc.wcBlocksData;
操作
receiveCollection(namespace, resourceName, queryString, ids = [], items = [], replace = false)
此操作将返回一个操作对象,该对象用于将集合结果分发到存储中,参数为给定的参数。
⚠️ 您通常不需要直接分发此操作,因为它由
getCollection选择器的解析器使用。
参数
- namespace
string: 集合的路由命名空间,例如/wc/blocks。 - resourceName
string: 集合的资源名称,例如products/attributes。 - queryString
string: 要添加到集合请求的附加查询字符串。 请注意,集合是根据查询字符串进行缓存的,例如?order=ASC。 - ids
array: 如果集合路由包含 ID 占位符,则您需要通过此参数提供这些 ID,顺序应与路由中占位符出现的顺序一致。 - response
Object: 一个包含items属性的对象,其中items属性包含来自响应的集合项(数组),以及一个headers属性,该属性与window.Headers界面匹配,包含来自响应的头部信息。 - replace
boolean: 指示是否应替换存储中给定索引(命名空间、资源名称、查询字符串)中已存在的任何项。
示例
const { dispatch } = useDispatch( COLLECTIONS_STORE_KEY );
dispatch( receiveCollection( namespace, resourceName, queryString, ids, response ) );
receiveCollectionError
此操作将返回一个操作对象,该对象用于将错误分发到存储中,参数为给定的参数。
参数
- namespace
string: 集合的路由命名空间,例如/wc/blocks。 - resourceName
string: 集合的资源名称,例如products/attributes。 - queryString
string: 要添加到集合请求的附加查询字符串。 请注意,集合是根据查询字符串进行缓存的,例如?order=ASC。 - ids
array: 如果集合路由包含 ID 占位符,则您需要通过此参数提供这些 ID,顺序应与路由中占位符出现的顺序一致。 - error
object: 包含以下键的错误对象:- code
string: 错误代码。 - message
string: 错误消息。 - data
object: 包含以下键的错误数据:- status
number: HTTP 状态码。 - params
object: 错误的参数。 - headers
object: 错误的头部信息。
- status
- code
Example
const { dispatch } = useDispatch( COLLECTIONS_STORE_KEY );
dispatch( receiveCollectionError( namespace, resourceName, queryString, ids, error ) );
receiveLastModified
此函数将返回一个动作对象,用于将修改日期发送到服务器。该对象使用在派发操作时提供的参数。
参数
- timestamp
number: 最后的修改日期的时间戳。
Example
const { dispatch } = useDispatch( COLLECTIONS_STORE_KEY );
dispatch( receiveLastModified( timestamp ) );
Selectors
getFromState
此选择器将返回来自 collections 存储的状态。
返回值
object: 来自 collections 存储的状态,包含以下属性:- namespace
string: collection 的路由命名空间,例如:/wc/blocks。 - resourceName
string: collection 的资源名称,例如:products/attributes。 - query
object: collection 的查询参数,例如:{ order: 'ASC', sortBy: Price }。 - ids
array: 如果 collection 路由包含用于提供占位符值的数组(按顺序)。 - type
string: collection 的类型,例如:items。
- namespace
或者
array|null|undefined: 如果 collection 缺少与提供的参数匹配的头部信息,则返回一个默认值(作为参数指定)。
Example
const store = select( COLLECTIONS_STORE_KEY );
const state = store.getFromState( state, namespace, resourceName, queryString, ids, type, fallback );
getCollection
此选择器将返回给定参数对应的 collection。 它有一个关联的解析器,如果选择器尚未被解析,则解析器会向服务器发送请求以获取 collection,并将结果发送到服务器。
返回值
object: 返回getFromState对象(参见getFromState)。
getCollectionHeader
此选择器将使用给定的参数从 collection 响应中返回一个头部信息。 它有一个关联的解析器,如果 getCollection 尚未被解析,则解析器将使用这些参数来解析 getCollection。
返回值
undefined: 如果集合包含头部,但没有与给定header参数匹配的头部,则返回undefined。
或者
null: 如果集合没有与给定参数匹配的任何头部,则返回null。
或者
object: 如果集合具有与给定参数匹配的头部,则返回一个包含以下属性的对象:- namespace
string: 集合的路由命名空间,例如:/wc/blocks。 - resourceName
string: 集合的资源名称,例如:products/attributes。 - header
string: 头部键。 - query
Object: 集合的查询参数,例如:{ order: 'ASC', sortBy: Price }。 - ids
Array: 如果集合路由包含用于提供占位符值的ids,则将这些值按顺序放在此数组中。
- namespace
getCollectionHeaders
此选择器将返回集合的头部信息。
返回值
object: 返回getFromState对象(请参阅getFromState)。
示例
const store = select( COLLECTIONS_STORE_KEY );
const headers = store.getCollectionHeaders( state, namespace, resourceName, queryString );
getCollectionError
此选择器将返回在获取集合时发生的任何错误。
返回值
object: 返回getFromState对象(请参阅getFromState)。
示例
const store = select( COLLECTIONS_STORE_KEY );
const error = store.getCollectionError( state, namespace, resourceName, queryString );
getCollectionLastModified
此选择器将返回集合的最后修改日期。
返回值
number: 集合的最后修改日期,如果不存在最后修改日期,则返回0。
示例
const store = select( COLLECTIONS_STORE_KEY );
const lastModified = store.getCollectionLastModified( state, namespace, resourceName, queryString );
支付存储 (`wc/store/payment`)
概述
支付数据存储用于存储支付方式数据和支付处理信息。当支付状态发生变化时,数据存储会反映这些变化。
⚠️ 目前,所有操作仅供内部使用,我们正在确定哪些操作对扩展程序与此数据存储进行交互是有用的。我们不鼓励扩展程序在此数据存储上分发操作。
以下示例显示了存储在支付数据存储中的数据。此示例显示了多个支付网关处于活动状态,并且保存了一个令牌的情况。
{
status: 'idle',
activePaymentMethod: 'stripe',
activeSavedToken: '1',
availablePaymentMethods: {
bacs: {
name: 'bacs'
},
cheque: {
name: 'cheque'
},
cod: {
name: 'cod'
},
stripe: {
name: 'stripe'
}
},
availableExpressPaymentMethods: {
payment_request: {
name: 'payment_request'
}
},
savedPaymentMethods: {
cc: [
{
method: {
gateway: 'stripe',
last4: '4242',
brand: 'Visa'
},
expires: '12/32',
is_default: true,
actions: {
'delete': {
url: 'https://store.local/checkout/delete-payment-method/1/?_wpnonce=123456',
name: 'Delete'
}
},
tokenId: 1
}
]
},
paymentMethodData: {
token: '1',
payment_method: 'stripe',
'wc-stripe-payment-token': '1',
isSavedToken: true
},
paymentResult: null,
paymentMethodsInitialized: true,
expressPaymentMethodsInitialized: true,
shouldSavePaymentMethod: false
}
用法
要使用此存储,您需要在引用它的任何模块中导入 paymentStore StoreDescriptor。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部,您可以通过以下方式导入键:
const { paymentStore } = window.wc.wcBlocksData;
选择器
getState
返回支付存储的当前状态。
🚨 避免使用此选择器,应使用专门的选择器。 此选择器仅用于在单元测试中模拟选择器。
返回值
object: 支付存储的当前状态,包含以下属性:_status_:string: 支付过程的当前状态。可能的值包括:idle(待审),started(已开始),processing(处理中),ready(就绪),error(错误),success(成功),failed(失败)。_activePaymentMethod_:string: 激活的付款方式的 ID。_activeSavedToken_:string: 激活的已保存令牌的 ID。_availablePaymentMethods_:object: 可用的付款方式。目前,它只是一个以付款方式 ID 为键的对象。每个成员包含一个name字段,其值为付款方式 ID。_availableExpressPaymentMethods_:object: 可用的快捷付款方式。目前,它只是一个以付款方式 ID 为键的对象。每个成员包含一个name字段,其值为付款方式 ID。_savedPaymentMethods_:object: 当前客户的已保存付款方式。这是一个对象,它将针对每种付款方式而有所不同。例如,Stripe 的已保存令牌将以如下方式返回:_paymentMethodData_:object: 当前的付款方式数据。这取决于每种付款方式,因此此处无法提供更多详细信息。_paymentResult_:object: 包含以下属性的对象: -_message_:string: 由支付网关返回的信息。 -_paymentStatus_:string: 付款的状态。可能的值包括:success(成功),failure(失败),pending(待审),error(错误),not set(未设置)。 -_paymentDetails_:object: 由支付网关返回的付款详情。 -_redirectUrl_:string: 结账完成后,用于重定向到的 URL。_paymentMethodsInitialized_:boolean: 如果已初始化付款方式,则为true,否则为false。_expressPaymentMethodsInitialized_:boolean: 如果已初始化快捷付款方式,则为true,否则为false。_shouldSavePaymentMethod_:boolean: 如果应保存付款方式,则为true,否则为false。
示例
const store = select( paymentStore );
const currentState = store.getState();
isPaymentIdle
查询付款状态是否为 idle (待审)。
返回值
boolean: 如果付款状态为idle(待审),则为true,否则为false。
示例
const store = select( paymentStore );
const isPaymentIdle = store.isPaymentIdle();
isExpressPaymentStarted
查询是否已点击快捷付款方式。
返回值
boolean: 如果已点击快捷付款方式的按钮,则为true,否则为false。
示例
const store = select( paymentStore );
const isExpressPaymentStarted = store.isExpressPaymentStarted();
isPaymentProcessing
查询付款状态是否为 processing (处理中)。
返回值
boolean: 如果付款状态为processing(处理中),则为true,否则为false。
示例
const store = select( paymentStore );
const isPaymentProcessing = store.isPaymentProcessing();
isPaymentReady
查询状态是否为 ready。
返回值
boolean: 如果付款状态为ready,则返回true,否则返回false。
示例
const store = select( paymentStore );
const isPaymentReady = store.isPaymentReady();
hasPaymentError
查询状态是否为 error。
返回值
boolean: 如果付款状态为error,则返回true,否则返回false。
示例
const store = select( paymentStore );
const hasPaymentError = store.hasPaymentError();
isExpressPaymentMethodActive
返回是否启用了快速付款方式。当快速付款方式打开并接收用户输入时,此值为 true。对于 Google Pay,当模态框打开时为 true,但其他付款方式可能具有不同的用户界面。
返回值
boolean: 是否启用了快速付款方式。
示例
const store = select( paymentStore );
const isExpressPaymentMethodActive = store.isExpressPaymentMethodActive();
getActiveSavedToken
返回当前激活的已保存令牌。客户保存到账户中的付款方式与之关联的令牌。如果选择了其中一个,则此选择器返回当前激活的令牌。如果没有选择任何令牌,则返回一个空字符串。
返回值
string: 当前激活的已保存令牌 ID,如果未选择任何已保存令牌,则返回空字符串。
示例
const store = select( paymentStore );
const activeSavedToken = store.getActiveSavedToken();
getActivePaymentMethod
返回当前激活的付款方式的 ID。
返回值
string: 当前激活的付款方式的 ID。
示例
const store = select( paymentStore );
const activePaymentMethod = store.getActivePaymentMethod();
getAvailablePaymentMethods
返回可用的付款方式。 这不包含快速付款方式。
返回值
object: 可用的付款方式。 目前,这只是一个以付款方式 ID 为键的对象。 每个成员都包含一个名为name的条目,其值为付款方式 ID。
示例
const store = select( paymentStore );
const availablePaymentMethods = store.getAvailablePaymentMethods();
availablePaymentMethods 将如下所示:
{
"cheque": {
name: "cheque",
},
"cod": {
name: "cod",
},
"bacs": {
name: "bacs",
},
}
getAvailableExpressPaymentMethods
返回可用的快速付款方式。
返回值
object: 可用的快速付款方式。 目前,这只是一个以付款方式 ID 为键的对象。 每个成员都包含一个名为name的条目,其值为付款方式 ID。
示例
const store = select( paymentStore );
const availableExpressPaymentMethods =
store.getAvailableExpressPaymentMethods();
availableExpressPaymentMethods 的结构如下:
{
"payment_request": {
name: "payment_request",
},
"other_express_method": {
name: "other_express_method",
},
}
getPaymentMethodData
返回当前的付款方式数据。 每次活动付款方式发生变化时,此数据都会改变,并且不会为每个付款方式持久化。 例如,如果客户选择了 PayPal,则付款方式数据将特定于该付款方式。 如果他们切换到 Stripe,则付款方式数据将被 Stripe 覆盖,之前的价值(当选择 PayPal 时)将不再可用。
返回值
object: 当前的付款方式数据。 这与每个付款方式相关,因此此处无法提供更多详情。
示例
const store = select( paymentStore );
const paymentMethodData = store.getPaymentMethodData();
getSavedPaymentMethods
返回当前客户的所有已保存的付款方式。
返回值
object: 当前客户的已保存的付款方式。 这是一个对象,它将特定于每个付款方式。 例如,Stripe 的已保存令牌以如下方式返回:
savedPaymentMethods: {
cc: [
{
method: {
gateway: 'stripe',
last4: '4242',
brand: 'Visa',
},
expires: '04/24',
is_default: true,
actions: {
wcs_deletion_error: {
url: '#choose_default',
name: 'Delete',
},
},
tokenId: 2,
},
];
}
示例
const store = select( paymentStore );
const savedPaymentMethods = store.getSavedPaymentMethods();
getActiveSavedPaymentMethods
返回当前客户的活动已保存的付款方式,即可以用于支付当前订单的付款方式。
返回值
object - 当前客户的活动已保存的付款方式,即可以用于支付此订单的付款方式。 这是一个对象,它将特定于每个付款方式。 例如,Stripe 的已保存令牌以如下方式返回:
activeSavedPaymentMethods: {
cc: [
{
method: {
gateway: 'stripe',
last4: '4242',
brand: 'Visa',
},
expires: '04/24',
is_default: true,
actions: {
wcs_deletion_error: {
url: '#choose_default',
name: 'Delete',
},
},
tokenId: 2,
},
];
}
示例
const store = select( paymentStore );
const activeSavedPaymentMethods = store.getActiveSavedPaymentMethods();
getIncompatiblePaymentMethods
返回与结账 Block 不兼容的付款方式列表。
返回值
object: 一个不兼容的付款方式列表,包含以下属性,如果未初始化任何付款方式或快捷付款方式,则返回一个空对象:- name
字符串: 付款方式的名称。
- name
示例
const store = select( paymentStore );
const incompatiblePaymentMethods = store.getIncompatiblePaymentMethods();
getShouldSavePaymentMethod
返回是否应将付款方式保存到客户的账户中。
返回值
boolean: 如果应保存付款方式,则返回true,否则返回false。
示例
const store = select( paymentStore );
const shouldSavePaymentMethod = store.getShouldSavePaymentMethod();
paymentMethodsInitialized
返回是否已初始化付款方式。
返回值
boolean: 如果已初始化付款方式,则返回true,否则返回false。
示例
const store = select( paymentStore );
const paymentMethodsInitialized = store.paymentMethodsInitialized();
expressPaymentMethodsInitialized
返回是否已初始化快捷付款方式。
返回值
boolean: 如果已初始化快捷付款方式,则返回 true,否则返回 false。
示例
const store = select( paymentStore );
const expressPaymentMethodsInitialized =
store.expressPaymentMethodsInitialized();
getPaymentResult
返回上次付款尝试的结果。
返回值
object: 一个包含以下属性的对象:
{
message: string;
paymentStatus: 'success' | 'failure' | 'pending' | 'error' | 'not set';
paymentDetails: Record< string, string > | Record< string, never >;
redirectUrl: string;
}
示例
const store = select( paymentStore );
const paymentResult = store.getPaymentResult();
(@deprecated) isPaymentPristine
查询 状态 是否为 pristine。
⚠️ 此选择器已过时,将在未来的版本中移除。请使用
isPaymentIdle代替。
返回值
boolean: 如果状态为pristine,则返回true,否则返回false。
示例
const store = select( paymentStore );
const isPaymentPristine = store.isPaymentPristine();
(@deprecated) isPaymentStarted
查询 状态 是否为 started。
⚠️ 此选择器已过时,将在未来的版本中移除。请使用
isExpressPaymentStarted代替。
返回值
boolean: 如果状态为started,则返回true,否则返回false。
示例
const store = select( paymentStore );
const isPaymentStarted = store.isPaymentStarted();
(@deprecated) isPaymentSuccess
查询 状态 是否为 success。
⚠️ 此选择器已过时,将在未来的版本中移除。请使用
isPaymentReady代替。
返回值
boolean: 如果状态为success,则返回true,否则返回false。
示例
const store = select( paymentStore );
const isPaymentSuccess = store.isPaymentSuccess();
(@deprecated) isPaymentFailed
查询付款的状态是否为failed。
⚠️ 此选择器已过时,将在未来的发布版本中被移除。请使用
hasPaymentError代替。
返回值
boolean: 如果付款状态为failed,则返回true,否则返回false。
示例
const store = select( paymentStore );
const isPaymentFailed = store.isPaymentFailed();
(@deprecated) getCurrentStatus
返回一个包含布尔值的对象,表示付款状态。
⚠️ 此选择器已过时,将在未来的发布版本中被移除。请使用上面的选择器。
返回值
object: 当前付款状态,包含以下键:- isPristine
boolean: 如果付款流程尚未开始,没有错误并且尚未完成,则返回true。 初始时为true。 - isStarted
boolean: 如果付款流程已经开始,则返回true。 - isProcessing
boolean: 如果付款正在处理中,则返回true。 - hasError
boolean: 如果付款流程导致了错误,则返回true。 - hasFailed
boolean: 如果付款流程失败,则返回true。 - isSuccessful
boolean: 如果付款流程成功,则返回true。 - isDoingExpressPayment
boolean: 如果启用了快速付款方法,则返回true,否则返回false。
- isPristine
示例
const store = select( paymentStore );
const currentStatus = store.getCurrentStatus();
查询状态商店 (`wc/store/query-state`)
概述
查询状态商店提供了操作,用于处理和操作与查询相关的数据,这些数据位于特定的上下文环境中,例如单个区块。 这有助于动态更新和检索查询状态值,从而确保 WooCommerce 区块中准确且具有上下文相关的的数据管理。
用法
要使用此商店,您需要在任何引用它的模块中导入 QUERY_STATE_STORE_KEY。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以通过以下方式导入密钥:
const { QUERY_STATE_STORE_KEY } = window.wc.wcBlocksData;
操作
⚠️ 新值将始终覆盖商店中任何现有的条目。
setQueryValue(context, queryKey, value)
此操作将设置给定上下文中的单个查询状态值。
参数
- context
string: 存储的查询状态的上下文,例如区块名称,以便为每个区块保持查询状态的特定性。 - queryKey
string: 存储值的引用。 - value
mixed: 要存储的实际查询状态值。
setValueForQueryContext(context, value)
此操作将设置给定上下文的查询状态。 通常,此操作用于设置/替换给定上下文的整个查询状态,而不是通过 setQueryValue 设置上下文中的各个键。
参数
- context
string: 存储的查询状态的上下文,例如区块名称,以便为每个区块保持查询状态的特定性。 - value
object: 附加到上下文的查询状态的键/值对对象。
结构化数据存储 (`wc/store/schema`)
概述
结构化数据存储管理与 WooCommerce Blocks 相关的路由,从而能够高效地检索和更新给定命名空间的路由数据。 此存储简化了与资源路由的交互,确保模块可以根据需要轻松访问端点路径。
用法
要使用此存储,您需要在任何引用它的模块中导入 SCHEMA_STORE_KEY。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部,您可以通过以下方式导入密钥:
const { SCHEMA_STORE_KEY } = window.wc.wcBlocksData;
操作
⚠️ 您通常不需要直接使用这些操作,因为它们主要由解析器在内部使用。
receiveRoutes(routes, namespace)
此操作返回一个对象,用于使用提供的资源路由列表更新存储。
参数
routesarray: 针对给定命名空间的路由数组,例如:[ '/wc/blocks/products', '/wc/blocks/products/attributes/(?P<id>[\d]+)' ]。namespacestring: 路由所属的命名空间,例如:/wc/blocks。
返回值
object: 一个操作对象,用于使用提供的资源路由列表更新存储,具有以下键:typestring: 操作类型。routesobject: 路由对象的集合,以路由名称作为键。namespacestring: 路由所属的命名空间,例如:/wc/blocks。
选择器
getRoute(state, namespace, resourceName, ids = [])
此方法用于检索给定命名空间、资源名称和(如果需要)ID 的路由。
参数
stateobject: 原始状态。namespacestring: 路由的命名空间,例如:/wc/blocks。resourceNamestring: 请求的资源,例如:products/attributes/terms。idsarray: 仅当路由包含 ID 占位符时才需要。
返回值
string: 如果路由可用,则返回该路由。
示例
如果您正在查找 wc/blocks 命名空间中单个产品的路由,则 ids 将为 [ 20 ]:
// '/wc/blocks/products/20'
wp.data.select( SCHEMA_STORE_KEY ).getRoute( '/wc/blocks', 'products', [ 20 ] );
getRoutes(state, namespace)
此方法将返回给定命名空间的所有已注册路由,并将其作为扁平数组返回。
参数
stateobject: 当前状态。namespacestring: 要返回路由的命名空间。
返回值
array: 包含给定命名空间的所有路由的数组。
getRouteFromResourceEntries
此方法将从路由状态的给定切片中返回路由。
参数
stateSliceobject: 从给定命名空间和资源名称的路由状态切片。idsarray(默认:[]): 一个 ID 引用数组,这些 ID 将替换为路由占位符。
返回值
string: 给定的资源条目的路由,如果未找到任何路由,则返回一个空字符串。
例子
const store = select( SCHEMA_STORE_KEY );
const route = store.getRouteFromResourceEntries( stateSlice, ids );
assembleRouteWithPlaceholders
此函数将返回带有占位符的组装后的路由。
参数
- route
string: 要组装的路由。 - routePlaceholders
array: 路由占位符的数组。 - ids
array: 要在路由占位符中替换的 ID 关键字的数组。
返回值
string: 组装后的路由,其中占位符已替换为实际的价值。
例子
const store = select( SCHEMA_STORE_KEY );
const route = store.assembleRouteWithPlaceholders( route, routePlaceholders, ids );
Store Notices Store (`wc/store/store-notices`)
概述
Store Notices Store 允许注册和取消注册用于显示通知的容器。 这对于在特定位置显示通知非常有用,例如自定义块。
使用方法
要使用此存储,您需要在任何引用它的模块中导入 storeNoticesStore StoreDescriptor。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以这样导入 StoreDescriptor:
import { storeNoticesStore } from '@woocommerce/block-data';
如果不是,则可以从 window 对象中访问它:
const { storeNoticesStore } = window.wc.wcBlocksData;
示例
以下代码片段演示了如何注册一个用于显示通知的容器。
import { store as noticesStore } from '@wordpress/notices';
export default function Block( attributes ) {
const context = 'your-namespace/custom-form-step';
dispatch( noticesStore ).createNotice(
'error',
'这是一个错误通知的示例。',
{ context }
);
return (
<>
<StoreNoticesContainer context={ context } />
{ /* 您的自定义块代码 */ }
</>
);
}
💡 内部,
StoreNoticesContainer组件将派发registerContainer操作。
请注意,这是一个简单的示例。 在实际应用中,您希望在用户操作(例如提交表单)时触发 createNotice 操作。
操作
registerContainer( containerContext )
此操作将注册一个新的容器。
参数
- containerContext
string: 要注册的容器的上下文或标识符。
返回值
object: 一个包含以下属性的操作对象:- type
string: 操作的类型。 - containerContext
string: 传递的 containerContext。
- type
示例
import { storeNoticesStore } from '@woocommerce/block-data';
dispatch( storeNoticesStore ).registerContainer( 'someContainerContext' );
unregisterContainer( containerContext )
此操作将取消注册一个现有的容器。
参数
- containerContext
string: 要取消注册的容器的上下文或标识符。
返回值
object: 一个包含以下属性的操作对象:- type
string: 操作的类型。 - containerContext
string: 传递的 containerContext。
- type
示例
import { storeNoticesStore } from '@woocommerce/block-data';
dispatch( storeNoticesStore ).unregisterContainer( 'someContainerContext' );
选择器
getRegisteredContainers
返回当前状态中已注册容器的列表。
返回值
string[]: 一个包含已注册容器上下文的字符串数组。
示例
import { storeNoticesStore } from '@woocommerce/block-data';
关于容器注册和管理的文档
本文档描述了如何注册和管理容器。
NOTICE: 请仔细阅读以下内容,以确保正确配置您的系统。
本系统允许您注册和管理容器。每个容器都必须在系统中进行注册,才能被使用。
以下是如何注册容器的步骤:
- 使用
register(containerName)命令注册一个新容器。 - 确保容器包含所有必需的文件和配置。
- 验证容器是否已成功注册。
以下是如何管理已注册容器的步骤:
- 使用
listContainers()命令列出所有已注册的容器。 - 使用
select(containerName)命令选择一个特定的容器。 - 使用
delete(containerName)命令删除一个容器。
重要提示: 确保您拥有足够的权限才能执行这些操作。
以下是一个示例代码片段,展示了如何注册和获取已注册的容器:
const store = select( storeNoticesStore );
const registeredContainers = store.getRegisteredContainers();
解释:
store:一个商店对象,用于存储和管理数据。select(storeNoticesStore):选择名为storeNoticesStore的商店。getRegisteredContainers():获取所有已注册的容器列表。
常见问题:
- 问题: 为什么我的容器无法注册?
- 答案: 确保您已满足所有注册要求,并且您拥有足够的权限。
- 问题: 我可以同时注册多少个容器?
- 答案: 这取决于您的系统配置。请查阅您的系统管理员。
- 问题: 如何更新已注册的容器?
- 答案: 您需要先删除该容器,然后重新注册它。
其他信息:
- 有关容器注册的更多信息,请访问 https://example.com/container-registration。
- 有关容器管理的更多信息,请访问 https://example.com/container-management。
希望本文档对您有所帮助。 如果您有任何问题,请联系我们的技术支持团队。
验证数据存储 (`wc/store/validation`)
概述
验证数据存储提供了一种在购物车或结账模块中显示字段错误的机制。
存储中的数据应该是一个单独的对象,其键是 错误 ID,值是与该错误信息相关的数据。对象中的值应该包含 message 和 hidden 字段。message 是要显示的错误信息,hidden 是一个布尔值,指示是否应该显示该错误。
以下是一个数据结构示例:
{
"error-id-1": {
message: "这是一个错误信息",
hidden: false,
},
"error-id-2": {
message: "这是另一个错误信息",
hidden: true,
},
}
当结账流程开始时,它将检查此数据存储是否包含任何条目,如果包含,则会阻止结账流程继续。它还会显示任何被隐藏的错误。将错误设置为隐藏不会将其从数据存储中清除!
用法
要使用此存储,您需要在引用它的任何模块中导入 validationStore StoreDescriptor。 假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以通过以下方式导入 StoreDescriptor:
const { validationStore } = window.wc.wcBlocksData;
示例
为了更好地理解验证存储 (Validation Store),让我们以古腾堡编辑器中“条款和条件”的必选复选框为例。在网页编辑器中,商家可以设置要求买家同意“条款和条件”,方法是使该复选框成为必选项。

在 WooCommerce Blocks 中,我们使用 useEffect 钩子来检查复选框是否为必选项以及是否已选中。如果复选框为必选项但未选中,我们将向存储添加一个验证错误。如果复选框为必选项且已选中,我们将从存储中清除验证错误。
useEffect( () => {
if ( ! checkbox ) {
return;
}
if ( checked ) {
clearValidationError( validationErrorId );
} else {
setValidationErrors( {
[ validationErrorId ]: {
message: __(
'Please read and accept the terms and conditions.',
'woo-gutenberg-products-block'
),
hidden: true,
},
} );
}
return () => {
clearValidationError( validationErrorId );
};
}, [
checkbox,
checked,
validationErrorId,
clearValidationError,
setValidationErrors,
] );
默认情况下,验证错误是隐藏的。这是因为我们不想在买家尝试提交表单之前显示错误信息。在提交结账表单之前,验证信息已经在验证存储中可见。

当买家在未选中“条款和条件”复选框的情况下提交结账表单时,hidden: true 将更改为 hidden: false,并且显示验证信息。

在 WooCommerce Blocks 中,我们使用以下代码检查文本输入字段是否具有验证错误:
const hasError = validationError?.message && ! validationError?.hidden;
💡 从这个示例中需要记住的主要内容是:
hidden: true表示存在验证错误,但该错误未显示给用户。hidden: false表示正在主动向用户显示验证错误。
在上面的示例中,message 是隐藏的,只有文字颜色变为红色,以突出显示该字段存在验证错误。
在某些情况下,希望向用户显示验证错误消息。例如,如果买家尝试在未填写必填字段的情况下提交结账表单。一个例子是当“名”、“姓氏”和“地址”字段为空时:

在 WooCommerce Blocks 中,以下函数处理验证错误消息的显示逻辑:
# 验证输入错误组件
该组件用于显示验证输入时的错误信息。
**功能:**
* 显示错误信息。
* 根据配置显示或隐藏错误信息。
* 提供错误 ID 用于定位错误元素。
**参数:**
| 参数名 | 类型 | 描述 |
| ---------------- | ---------- | -------------------------------------- |
| `errorMessage` | `string` | 错误信息,如果未提供,则尝试从 `validationError` 获取。 |
| `propertyName` | `string` | 属性名,用于从验证商店获取错误信息。 |
| `elementId` | `string` | 元素 ID,用于获取错误 ID。 |
**返回值:**
* `JSX.Element | null`: 如果存在错误信息,则返回包含错误信息的 `div` 元素;否则,返回 `null`。
**代码示例:**
```ts
export const ValidationInputError = ( {
errorMessage = '',
propertyName = '',
elementId = '',
}: ValidationInputErrorProps ): JSX.Element | null => {
const { validationError, validationErrorId } = useSelect( ( select ) => {
const store = select( validationStore );
return {
validationError: store.getValidationError( propertyName ),
validationErrorId: store.getValidationErrorId( elementId ),
};
} );
if ( ! errorMessage || typeof errorMessage !== 'string' ) {
if ( validationError?.message && ! validationError?.hidden ) {
errorMessage = validationError.message;
} else {
return null;
}
}
return (
<div className="wc-block-components-validation-error" role="alert">
<p id={ validationErrorId }>{ errorMessage }</p>
</div>
);
};
上述代码片段的简化版本如下:
{
validationError?.hidden === false && (
<div className="wc-block-components-validation-error" role="alert">
<p>{ validationError?.message }</p>
</div>
);
}
说明:
ValidationInputError组件接收errorMessage、propertyName和elementId作为参数。- 如果
errorMessage未提供,组件会尝试从validationError对象获取错误信息。 useSelect钩子用于从validationStore获取验证错误信息和错误 ID。role="alert"属性用于指示该元素是一个警报。- 如果
validationError对象存在且hidden属性为false,则显示错误信息。 - 如果
errorMessage为空或不是字符串类型,则从validationError对象获取错误信息。 - 如果
validationError对象不存在或hidden属性为true,则不显示任何内容。
使用方法:
<ValidationInputError
errorMessage="请输入正确的邮箱地址"
propertyName="email"
elementId="email-input"
/>
注意事项:
- 确保
validationStore已经正确初始化。 propertyName和elementId必须与验证配置中的值相匹配。- 可以根据需要自定义错误信息的样式。
## 操作
### `clearValidationError(errorId)`
清除一个验证错误。
#### 参数
- `_errorId_` `string`: 用于清除验证错误的错误 ID。
#### 示例
```js
const store = dispatch(validationStore);
store.clearValidationError('billing-first-name');
clearValidationErrors(errors)
一次性清除多个验证错误。 如果未传递任何错误 ID,则将清除所有验证错误。
参数
_errors_string[]或undefined: 用于清除验证错误的错误 ID。 它可以是未定义,如果是,则将清除所有验证错误。
示例
- 这将仅清除数组中指定的验证错误。
const store = dispatch(validationStore);
store.clearValidationErrors([
'billing-first-name',
'billing-last-name',
'terms-and-conditions',
]);
- 这将清除所有验证错误。
const store = dispatch(validationStore);
store.clearValidationErrors();
setValidationErrors(errors)
设置验证错误。 errors 中的条目将被 添加到 验证错误列表中。 列表中已存在的条目将使用新值进行 更新。
参数
_errors_object: 新的验证错误,对象的键是验证错误 ID,值应该是包含messagestring和hiddenboolean的对象。
示例
const { dispatch } = wp.data;
const { setValidationErrors } = dispatch(validationStore);
setValidationErrors({
'billing-first-name': {
message: '名 不能为空。',
hidden: false,
},
'billing-last-name': {
message: '姓氏 不能为空。',
hidden: false,
},
});
hideValidationError(errorId)
参数
_errorId_string: 要隐藏的错误 ID。
示例
const { dispatch } = wp.data;
const { hideValidationError } = dispatch(validationStore);
hideValidationError('billing-first-name');
showValidationError(errorId)
参数
_errorId_string: 要显示的错误 ID。
示例
const { dispatch } = wp.data;
const { showValidationError } = dispatch(validationStore);
showValidationError('billing-first-name');
showAllValidationErrors
示例
const { dispatch } = wp.data;
const { showAllValidationErrors } = dispatch(validationStore);
showAllValidationErrors();
clearAllValidationErrors
通过从商店中删除它们来清除所有验证错误。
示例
const { clearAllValidationErrors } = dispatch(validationStore);
clearAllValidationErrors();
选择器
getValidationError( errorId )
返回验证错误。
参数
- errorId
string: 用于获取验证错误的错误 ID。
返回值
object: 验证错误,是一个包含messagestring和hiddenboolean的对象。
示例
const store = select( validationStore );
const billingFirstNameError = store.getValidationError( 'billing-first-name' );
getValidationErrorId( errorId )
获取一个用于 HTML 的验证错误 ID,可以将其用作 CSS 选择器,或用于引用错误消息。 如果验证错误 hidden 设置为 true,或者验证错误在商店中不存在,则此方法将返回以 validate-error- 为前缀的错误 ID。
参数
- errorId
string: 用于获取验证错误 ID 的错误 ID。
返回值
string: 用于 HTML 的验证错误 ID。
示例
const store = select( validationStore );
const billingFirstNameErrorId =
store.getValidationErrorId( 'billing-first-name' );
getValidationErrors
返回商店中的所有验证错误。
返回值
Record<string, FieldValidationStatus>: 所有验证错误,其中键是错误 ID,值是包含messagestring和hiddenboolean的 FieldValidationStatus 对象。
示例
const store = select( validationStore );
const allValidationErrors = store.getValidationErrors();
hasValidationErrors
如果发生验证错误,则返回 true,否则返回 false。
返回值
boolean: 是否发生验证错误。
示例
const store = select( validationStore );
const hasValidationErrors = store.hasValidationErrors();
商店通知商店 (`wc/store/store-notices`)
概述
商店通知商店允许注册和注销通知容器。这对于在特定位置(例如自定义区块)显示通知非常有用。
用法
要使用此商店,您需要在任何引用它的模块中汇入 storeNoticesStore 的 StoreDescriptor。假设 @woocommerce/block-data 已注册为指向 wc.wcBlocksData 的外部依赖,您可以通过以下方式汇入 StoreDescriptor:
import { storeNoticesStore } from '@woocommerce/block-data';
如果未注册,则从 window 对象访问它,如下所示:
const { storeNoticesStore } = window.wc.wcBlocksData;
示例
以下代码片段演示了如何为通知注册容器。
import { store as noticesStore } from '@wordpress/notices';
export default function Block( attributes ) {
const context = 'your-namespace/custom-form-step';
dispatch( noticesStore ).createNotice(
'error',
'This is an example of an error notice.',
{ context }
);
return (
<>
<StoreNoticesContainer context={ context } />
{ /* 你的自定义区块代码放在这里 */ }
</>
);
}
💡 在内部,
StoreNoticesContainer组件将派发registerContainer操作。
请注意,这是一个简单的示例。在实践中,你可能会希望在响应用户操作(例如提交表单)时触发 createNotice 操作。
操作
registerContainer( containerContext )
此操作将注册一个新的容器。
参数
- containerContext
string: 要注册的容器的上下文或标识符。
返回
object: 一个包含以下属性的操作对象:- type
string: 操作的类型。 - containerContext
string: 通过的 containerContext。
- type
例子
import { storeNoticesStore } from '@woocommerce/block-data';
dispatch( storeNoticesStore ).registerContainer( 'someContainerContext' );
unregisterContainer( containerContext )
此操作将注销一个现有的容器。
参数
- containerContext
string: 要取消注册的容器的上下文或标识符。
返回值
object: 一个包含以下属性的操作对象:- type
string: 操作的类型。 - containerContext
string: 通过的 containerContext。
- type
例子
import { storeNoticesStore } from '@woocommerce/block-data';
dispatch( storeNoticesStore ).unregisterContainer( 'someContainerContext' );
选择器
getRegisteredContainers
从状态中返回当前已注册容器的列表。
返回值
string[]: 一个包含已注册容器上下文的字符串数组。
例子
import { storeNoticesStore } from '@woocommerce/block-data';
const store = select( storeNoticesStore );
const registeredContainers = store.getRegisteredContainers();
短代码的钩子替代方案
以下是加载购物车/结账短代码和块时运行的钩子。其中一些是通用的 WooCommerce 生命周期钩子,另一些是特定于购物车和结账页面的钩子。这些是通过记录每次 do_action 和 apply_filters 的调用,并审查提到 "钩子" 和 "过滤器" 的旧 WooCommerce Blocks 仓库 中的问题而生成的。
术语表
| 图标 | 描述 |
|---|---|
| ✅ | 完全支持 |
| 🔶 | 部分支持 |
| ❌ | 不支持 |
| ❓ | 未知 |
如果一个钩子被标记为未知 ❓,这意味着我们无法验证该钩子是否受支持,原因不明。 随着时间的推移,我们将尝试验证更多这些钩子。 目标是使所有表格中都不要再有任何具有未知 ❓ 状态的钩子。
WooCommerce 生命周期 操作
这些钩子在每个 WooCommerce 页面加载时运行,有些会影响块,有些不会,有些只部分影响它们。
| 旧钩子 | 在块中有效? | 备注 |
|---|---|---|
woocommerce_load_cart_from_session |
完全支持 ✅ | |
woocommerce_cart_loaded_from_session |
完全支持 ✅ | |
woocommerce_set_cart_cookies |
完全支持 ✅ | |
woocommerce_shipping_zone_loaded |
完全支持 ✅ | |
woocommerce_check_cart_items |
完全支持 ✅ | 建议使用 woocommerce_store_api_validate_cart_item |
woocommerce_before_calculate_totals |
完全支持 ✅ | |
woocommerce_shipping_init |
完全支持 ✅ | |
woocommerce_load_shipping_methods |
完全支持 ✅ | |
woocommerce_cart_calculate_fees |
完全支持 ✅ | |
woocommerce_calculate_totals |
完全支持 ✅ | |
woocommerce_after_calculate_totals |
完全支持 ✅ | |
woocommerce_cart_updated |
完全支持 ✅ | |
woocommerce_before_get_rates_for_package |
完全支持 ✅ | |
woocommerce_after_get_rates_for_package |
完全支持 ✅ | |
woocommerce_checkout_init |
完全支持 ✅ | |
woocommerce_customer_loaded |
完全支持 ✅ |
WooCommerce 生命周期 筛选
本节描述了 WooCommerce 提供的各种生命周期事件,这些事件允许您通过 筛选 来修改 WooCommerce 的行为。
什么是 筛选?
筛选 允许您在 WooCommerce 的特定事件发生时,修改其默认行为。 您可以将自定义函数连接到这些 筛选,以便在事件发生时执行您的代码。
如何使用 筛选?
要使用 筛选,您需要:
- 找到您想要修改的事件的 筛选 名称。
- 使用
add_filter()函数,将您的自定义函数连接到该 筛选。 - 在您的自定义函数中,修改事件的默认值。
示例:
假设您想修改 WooCommerce 订单总价的计算方式。 您可以使用 woocommerce_order_total 筛选 来实现这一点。
<?php
add_filter( 'woocommerce_order_total', 'custom_order_total' );
function custom_order_total( $total ) {
// 在这里添加您的自定义逻辑来计算订单总价
$total = $total + 10; // 例如,增加 10 元
return $total;
}
?>
常用的 WooCommerce 筛选:
以下是一些常用的 WooCommerce 筛选,以及它们所触发的事件:
woocommerce_checkout_order_process: 在用户完成结账时触发。woocommerce_email_order_meta_fields: 在发送订单邮件时,允许您添加自定义元数据字段。woocommerce_product_categories_tree_children_render: 用于自定义产品分类树的渲染方式。woocommerce_product_thumbnail: 用于修改产品缩略图。woocommerce_payment_complete: 在支付完成后触发。
更多信息:
有关 WooCommerce 筛选 的更多信息,请参阅 WooCommerce 的官方文档:https://woocommerce.com/document/developers/
重要提示:
- 在使用 筛选 时,请务必小心,并确保您的自定义代码不会影响 WooCommerce 的正常运行。
- 在修改任何 筛选 之前,请务必备份您的网站。
- 如果您不确定如何使用 筛选,请咨询专业的 WooCommerce 开发人员。
示例:修改产品价格
以下示例展示了如何使用 woocommerce_price 筛选 来修改产品价格:
<?php
add_filter( 'woocommerce_price', 'custom_product_price', 10, 2 );
function custom_product_price( $price, $product ) {
// 仅对特定产品修改价格
if ( $product->get_id() == 123 ) { // 假设产品 ID 为 123
$price = $price * 0.9; // 降低 10%
}
return $price;
}
?>
示例:修改产品描述
以下示例展示了如何使用 woocommerce_product_description 筛选 来修改产品描述:
<?php
add_filter( 'woocommerce_product_description', 'custom_product_description', 10, 1 );
function custom_product_description( $description ) {
// 在产品描述的开头添加一段自定义文本
$custom_text = '<p>这是一段自定义文本,将在产品描述的开头显示。</p>';
return $custom_text . $description;
}
?>
示例:修改产品图片大小
以下示例展示了如何使用 woocommerce_product_image_src 筛选 来修改产品图片大小:
<?php
add_filter( 'woocommerce_product_image_src', 'custom_product_image_size', 10, 3 );
function custom_product_image_size( $image_src, $size, $product ) {
// 仅对特定产品修改图片大小
if ( $product->get_id() == 456 ) { // 假设产品 ID 为 456
$image_src = str_replace( array( 'woocommerce-small', 'woocommerce-medium', 'woocommerce-large' ), 'woocommerce-large', $image_src ); // 强制使用 large 尺寸
}
return $image_src;
}
?>
希望这些示例能够帮助您更好地理解如何使用 WooCommerce 筛选。 请记住,在使用 筛选 时,请务必小心
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_notice_types |
Unknown ❓ | WC Blocks does not handle additional notice types outside of the core ones. Non-supported notices would be displayed as "info" notices. |
woocommerce_kses_notice_allowed_tags |
Unknown ❓ | |
woocommerce_product_get_stock_status |
Fully supported ✅ | |
woocommerce_product_is_in_stock |
Fully supported ✅ | |
woocommerce_product_get_manage_stock |
Unknown ❓ | |
woocommerce_product_get_tax_class |
Fully supported ✅ | |
woocommerce_product_get_tax_status |
Unknown ❓ | |
woocommerce_prices_include_tax |
Unknown ❓ | |
woocommerce_apply_base_tax_for_local_pickup |
Unknown ❓ | |
woocommerce_local_pickup_methods |
Not supported ❌ | Does not affect the blocks-based local pickup methods |
woocommerce_customer_get_shipping_postcode |
Fully supported ✅ | |
woocommerce_customer_get_shipping_city |
Fully supported ✅ | |
woocommerce_customer_taxable_address |
Unknown ❓ | |
woocommerce_shipping_methods |
Fully supported ✅ | |
woocommerce_format_localized_price |
Unknown ❓ | |
woocommerce_shipping_local_pickup_option |
Not supported ❌ | Does not affect the blocks-based local pickup methods |
woocommerce_shipping_pickup_location_option |
Unknown ❓ | Unsure if changing this changes the way local pickup shows in the Cart/Checkout |
woocommerce_shipping_method_supports |
Fully supported ✅ | |
woocommerce_get_tax_location |
Unknown ❓ | |
woocommerce_format_postcode |
Unknown ❓ | |
woocommerce_matched_tax_rates |
Unknown ❓ | |
woocommerce_find_rates |
Unknown ❓ | |
woocommerce_matched_rates |
Unknown ❓ | |
woocommerce_cart_totals_get_item_tax_rates |
Fully supported ✅ | |
woocommerce_adjust_non_base_location_prices |
Unknown ❓ | |
woocommerce_product_is_taxable |
Fully supported ✅ | |
woocommerce_price_ex_tax_amount |
Fully supported ✅ | |
woocommerce_tax_round |
Fully supported ✅ | |
woocommerce_calc_tax |
Fully supported ✅ | |
woocommerce_calculate_item_totals_taxes |
Fully supported ✅ | |
woocommerce_cart_ready_to_calc_shipping |
Fully supported ✅ | |
woocommerce_product_get_virtual |
Fully supported ✅ | |
woocommerce_is_virtual |
Fully supported ✅ | |
woocommerce_product_needs_shipping |
Fully supported ✅ | |
woocommerce_cart_needs_shipping |
Fully supported ✅ | |
woocommerce_customer_get_shipping_address_1 |
Fully supported ✅ | |
woocommerce_customer_get_shipping_address_2 |
Fully supported ✅ | |
woocommerce_cart_display_prices_including_tax |
Fully supported ✅ | |
woocommerce_cart_get_subtotal |
Fully supported ✅ | |
woocommerce_cart_shipping_packages |
Fully supported ✅ | |
woocommerce_product_get_shipping_class_id |
Fully supported ✅ | |
woocommerce_countries_shipping_countries |
Fully supported ✅ | |
woocommerce_get_zone_criteria |
Fully supported ✅ | |
woocommerce_shipping_zone_shipping_methods |
Fully supported ✅ | |
woocommerce_shipping_free_shipping_is_available |
Unknown ❓ | |
woocommerce_product_get_name |
Fully supported ✅ | |
woocommerce_shipping_method_add_rate |
Fully supported ✅ | |
woocommerce_shipping_flat_rate_is_available |
Fully supported ✅ | |
woocommerce_evaluate_shipping_cost_args |
Fully supported ✅ | |
woocommerce_calc_shipping_tax |
Fully supported ✅ | |
woocommerce_localisation_address_formats |
Fully supported ✅ | |
woocommerce_countries_base_country |
Unknown ❓ | |
woocommerce_formatted_address_force_country_display |
Unknown ❓ | |
woocommerce_states |
Fully supported ✅ | |
woocommerce_formatted_address_replacements |
Unknown ❓ | |
woocommerce_package_rates |
Fully supported ✅ | |
woocommerce_shipping_packages |
Fully supported ✅ | |
woocommerce_shipping_rate_method_id |
Fully supported ✅ | |
woocommerce_shipping_rate_taxes |
Fully supported ✅ | |
woocommerce_shipping_rate_cost |
Fully supported ✅ | |
woocommerce_cart_totals_get_fees_from_cart_taxes |
Fully supported ✅ | |
woocommerce_calculated_total |
Not supported ❌ | This does not seem to have any effect |
woocommerce_cart_get_discount_total |
Fully supported ✅ | |
woocommerce_cart_get_cart_contents_total |
Fully supported ✅ | |
woocommerce_get_price_excluding_tax |
Not supported ❌ | This does not seem to have any effect |
raw_woocommerce_price |
Not supported ❌ | This does not seem to have any effect |
formatted_woocommerce_price |
Not supported ❌ | This does not seem to have any effect |
woocommerce_price_trim_zeros |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_cart_page_permalink |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_cart_url |
Not supported ❌ | This does not seem to have any effect |
woocommerce_checkout_registration_enabled |
Fully supported ✅ | This does not seem to have any effect |
woocommerce_get_checkout_page_permalink |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_checkout_url |
Not supported ❌ | This does not seem to have any effect |
woocommerce_checkout_get_value |
Not supported ❌ | This does not seem to have any effect |
woocommerce_default_address_fields |
Not supported ❌ | This does not seem to have any effect |
default_checkout_billing_country |
Not supported ❌ | This does not seem to have any effect |
default_checkout_shipping_country |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_country_locale |
Fully supported ✅ | |
woocommerce_get_country_locale_default |
Unknown ❓ | |
woocommerce_get_country_locale_base |
Unknown ❓ | |
woocommerce_billing_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_shipping_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_checkout_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_cart_item_product |
Not supported ❌ | Modifying individual cart items is not possible |
woocommerce_payment_gateway_supports |
Fully supported ✅ | |
woocommerce_customer_get_billing_first_name |
Fully supported ✅ | |
woocommerce_customer_get_billing_last_name |
Fully supported ✅ | |
woocommerce_customer_get_billing_company |
Fully supported ✅ | |
woocommerce_customer_get_billing_address_1 |
Fully supported ✅ | |
woocommerce_customer_get_billing_address_2 |
Fully supported ✅ | |
woocommerce_customer_get_billing_city |
Fully supported ✅ | |
woocommerce_customer_get_billing_postcode |
Fully supported ✅ | |
woocommerce_customer_get_billing_phone |
Fully supported ✅ | |
woocommerce_customer_get_shipping_first_name |
Fully supported ✅ | |
woocommerce_customer_get_shipping_last_name |
Fully supported ✅ | |
woocommerce_customer_get_shipping_company |
Fully supported ✅ | |
woocommerce_get_item_data |
Partially supported 🔶 | Checkout blocks strip most HTML from metadata, allowing only a, b, em, i, strong, br, abbr, and span. |
woocommerce_cart_get_subtotal_tax |
Not supported ❌ | This does not seem to have any effect |
woocommerce_shipping_package_name |
Fully supported ✅ | |
woocommerce_shipping_rate_id |
Unknown ❓ | |
woocommerce_shipping_rate_label |
Fully supported ✅ | |
woocommerce_cart_get_shipping_taxes |
Fully supported ✅ | |
woocommerce_cart_get_fee_taxes |
Fully supported ✅ | |
woocommerce_cart_get_taxes |
Fully supported ✅ | |
woocommerce_rate_code |
Unknown ❓ | |
woocommerce_rate_compound |
Unknown ❓ | |
woocommerce_rate_label |
Fully supported ✅ | |
woocommerce_cart_hide_zero_taxes |
Unknown ❓ | |
woocommerce_cart_tax_totals |
Fully supported ✅ | |
woocommerce_cart_needs_payment |
Fully supported ✅ | |
woocommerce_order_class |
Fully supported ✅ | |
woocommerce_checkout_registration_required |
Unknown ❓ | |
woocommerce_privacy_policy_page_id |
Fully supported ✅ | |
woocommerce_get_terms_page_id |
Unknown ❓ | |
woocommerce_terms_and_conditions_page_id |
Unknown ❓ | |
woocommerce_cart_contents_count |
Unknown ❓ | |
woocommerce_country_locale_field_selectors |
Not supported ❌ | |
woocommerce_get_return_url |
Fully supported ✅ | |
woocommerce_cart_hash |
Fully supported ✅ | |
woocommerce_cart_get_fee_tax |
Fully supported ✅ | |
woocommerce_customer_default_location_array |
Fully supported ✅ | |
woocommerce_countries |
Fully supported ✅ | |
woocommerce_sort_countries |
Not supported ❌ | This does not seem to have any effect |
woocommerce_countries_allowed_countries |
Fully supported ✅ | |
woocommerce_customer_default_location_array |
Fully supported ✅ | |
woocommerce_customer_get_billing_country |
Fully supported ✅ | |
woocommerce_customer_get_shipping_country |
Fully supported ✅ | |
woocommerce_customer_get_billing_state |
Fully supported ✅ | |
woocommerce_customer_get_shipping_state |
Fully supported ✅ | |
woocommerce_customer_get_billing_email |
Fully supported ✅ | |
woocommerce_cart_session_initialize |
Fully supported ✅ | |
woocommerce_get_checkout_page_id |
Fully supported ✅ | |
woocommerce_get_cart_page_id |
Fully supported ✅ | |
woocommerce_is_checkout |
Fully supported ✅ | |
woocommerce_currency |
Fully supported ✅ | |
woocommerce_currency_symbols |
Fully supported ✅ | |
woocommerce_currency_symbol |
Fully supported ✅ | |
woocommerce_price_format |
Fully supported ✅ | |
woocommerce_coupons_enabled |
Fully supported ✅ | |
woocommerce_get_shop_page_id |
Fully supported ✅ | |
current_theme_supports-woocommerce |
Fully supported ✅ | |
woocommerce_payment_gateways |
Partially supported 🔶 | Integration with WC Blocks is still required, beyond unsetting gateways, manipulating the payment gateways here may not work in the Cart and Checkout blocks |
woocommerce_get_base_location |
Fully supported ✅ | |
woocommerce_gateway_icon |
Not supported ❌ | This hook has no effect since icons are not displayed. |
woocommerce_get_image_size_thumbnail |
Fully supported ✅ | |
woocommerce_get_image_size_single |
Fully supported ✅ | |
woocommerce_product_stock_status_options |
Fully supported ✅ | |
woocommerce_cart_item_name |
Not supported ❌ | Use the itemName checkout filter. |
woocommerce_product_get_status |
Fully supported ✅ | |
woocommerce_product_get_price |
Fully supported ✅ | |
woocommerce_is_purchasable |
Fully supported ✅ | |
woocommerce_cart_item_is_purchasable |
Fully supported ✅ | |
woocommerce_cart_item_data_to_validate |
Fully supported ✅ | |
woocommerce_get_cart_item_from_session |
Fully supported ✅ | |
woocommerce_cart_contents_changed |
Fully supported ✅ | |
woocommerce_get_cart_contents |
Fully supported ✅ | |
woocommerce_stock_amount |
Fully supported ✅ | |
woocommerce_cart_item_remove_link |
Not supported ❌ | Use the showRemoveItemLink checkout filter. |
woocommerce_cart_item_quantity |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_product_get_image |
Not supported ❌ | Use woocommerce_store_api_cart_item_images (PR Link with example.) |
woocommerce_cart_no_shipping_available_html |
Not supported ❌ | This is not editable |
woocommerce_available_payment_gateways |
Partially supported 🔶 | Integration with WC Blocks is still required, beyond unsetting gateways, manipulating the payment gateways here may not work in the Cart and Checkout blocks |
woocommerce_cart_get_total |
Fully supported ✅ | |
woocommerce_cart_get_fee_tax |
Fully supported ✅ | |
woocommerce_cart_get_cart_contents_tax |
Fully supported ✅ | |
woocommerce_cart_get_shipping_tax |
Fully supported ✅ | |
woocommerce_cart_get_shipping_total |
Fully supported ✅ |
购物车 操作
Add item to cart
将商品添加到购物车。
View cart
查看购物车。
Remove item from cart
从购物车中移除商品。
Update item quantity in cart
更新购物车中商品的数量。
Clear cart
清空购物车。
Checkout
结账。
Example:
// Example code
function addItemToCart(item) {
// Add item to the cart
}
Explanation:
AddItemToCart操作用于将商品添加到购物车。ViewCart操作用于查看购物车中的商品。RemoveItemFromCart操作用于从购物车中移除商品。UpdateItemQuantityInCart操作用于更新购物车中商品的数量。ClearCart操作用于清空购物车。Checkout操作用于完成购买流程。
Note:
%s是一个占位符,可以替换为任何字符串。%d是一个占位符,可以替换为任何整数。{name}是一个占位符,可以替换为任何名称。on表示设备或功能处于开启状态。
规则:
- 翻译所有英文文本,包括标题、段落、列表项
- 保持 Markdown 格式不变(#、**、``、 等)
- 代码块(
...)内的代码不翻译,只翻译代码块外的文本 - 保留所有占位符(%s, %d, {name})和 HTML 标签
- 保留所有 URL 链接地址不翻译
- 函数名、变量名、命令名保留英文原文
- 只输出翻译结果,不要输出解释或原文
术语表(必须使用以下译法):
- Available → 可用
- Discount → 折扣
- Position → 位置
- Quantity → 数量
- Contents → 内容
- manually → 手动
- Shipping → 配送
- Checkout → 结账
- Actions → 操作
- Orders → 订单
- Button → 按钮
- Before → 前
- Manual → 手册
- Coupon → 优惠券
- Hooks → 钩子
- Close → 关闭
- Field → 字段
- After → 后
- Input → 输入
- check → 检查
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_before_cart |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 也可以使用 render_block_{$name} 过滤器,通过 PHP 在前后添加块。 |
woocommerce_before_cart_table |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_before_cart_contents |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_after_cart_item_name |
Not supported ❌ | 使用 itemName 结账过滤器。 |
woocommerce_before_quantity_input_field |
Not supported ❌ | 目前没有等效项。 |
woocommerce_after_quantity_input_field |
Not supported ❌ | 目前没有等效项。 |
woocommerce_cart_contents |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_cart_coupon |
Not supported ❌ | ExperimentalDiscountsMeta slot/fill |
woocommerce_cart_actions |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_after_cart_contents |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_after_cart_table |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_before_cart_collaterals |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_cart_collaterals |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
woocommerce_before_cart_totals |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_cart_totals_before_shipping |
Not supported ❌ | ExperimentalOrderShippingPackages |
woocommerce_after_shipping_rate |
Not supported ❌ | ExperimentalOrderShippingPackages |
woocommerce_before_shipping_calculator |
Not supported ❌ | 没有特定的等效项。 最接近的是 ExperimentalOrderShippingPackages |
woocommerce_after_shipping_calculator |
Not supported ❌ | 没有特定的等效项。 最接近的是 ExperimentalOrderShippingPackages |
woocommerce_cart_totals_after_shipping |
Not supported ❌ | 没有特定的等效项。 最接近的是 ExperimentalOrderShippingPackages |
woocommerce_cart_totals_before_order_total |
Not supported ❌ | 没有特定的等效项,但我们有总价部分的过滤器。 |
woocommerce_cart_totals_after_order_total |
Not supported ❌ | 没有特定的等效项,但我们有总价部分的过滤器。 |
woocommerce_proceed_to_checkout |
Not supported ❌ | 没有特定的等效项,但结账和“提交订单”按钮的过滤器可能有效。 |
woocommerce_after_cart_totals |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_after_cart |
Not supported ❌ | 没有特定的等效项,也没有可用的 Slot/fill 位置。 也许向 "购物车商品" 块添加一个内部块可以实现,但必须由商家手动进行位置调整。 |
购物车 筛选
本节描述如何使用 筛选 功能来管理购物车中的商品。
购物车筛选功能
购物车筛选功能允许用户根据各种条件过滤购物车中的商品,例如:
- 商品类型: 可以根据商品类型进行筛选,例如:服装、电子产品、书籍等。
- 价格范围: 可以根据价格范围进行筛选,例如:低于 100 元、100-200 元、高于 200 元等。
- 品牌: 可以根据品牌进行筛选,例如:Nike、Adidas、Apple 等。
- 库存: 可以根据库存数量进行筛选,例如:仅显示有库存的商品。
使用方法
要使用购物车筛选功能,请按照以下步骤操作:
- 打开购物车页面。
- 点击“筛选”按钮。
- 在弹出的筛选窗口中,选择要应用的筛选条件。
- 点击“应用”按钮。
示例
以下是一个使用购物车筛选功能的示例:
假设您想筛选购物车中所有价格低于 100 元的服装商品。
- 打开购物车页面。
- 点击“筛选”按钮。
- 在筛选窗口中,选择“商品类型”为“服装”,并选择“价格范围”为“低于 100 元”。
- 点击“应用”按钮。
购物车页面将只显示价格低于 100 元的服装商品。
高级用法
购物车筛选功能还支持一些高级用法,例如:
- 多条件筛选: 可以同时应用多个筛选条件。
- 自定义筛选条件: 可以根据需要自定义筛选条件。
有关高级用法的更多信息,请参考相关文档。
代码示例
以下是一个使用 Python 语言实现购物车筛选功能的示例代码:
def filter_cart(cart, filters):
"""
Filters a cart based on the given filters.
Args:
cart: A list of items in the cart.
filters: A dictionary of filters.
Returns:
A list of items in the cart that match the filters.
"""
filtered_cart = []
for item in cart:
match = True
for key, value in filters.items():
if key == "type" and item["type"] != value:
match = False
elif key == "price" and item["price"] > value:
match = False
if match:
filtered_cart.append(item)
return filtered_cart
# Example usage
cart = [
{"name": "T-shirt", "type": "clothing", "price": 20},
{"name": "Jeans", "type": "clothing", "price": 50},
{"name": "Laptop", "type": "electronics", "price": 1000},
]
filters = {"type": "clothing", "price": 50}
filtered_cart = filter_cart(cart, filters)
print(filtered_cart)
错误处理
如果在应用筛选功能时出现错误,请检查以下事项:
- 确保已正确配置筛选条件。
- 确保购物车中存在符合筛选条件的商品。
- 如果问题仍然存在,请联系技术支持。
相关链接
希望本节内容对您有所帮助。如有任何疑问,请随时联系我们。
规则说明
本文档提供了关于 WooCommerce 块的 Hook 支持情况说明。
旧的 Hook |
是否支持块? | 备注 |
|---|---|---|
woocommerce_cart_item_product_id |
不支持 ❌ | 似乎没有任何效果。 |
woocommerce_cart_item_visible |
不支持 ❌ | 似乎没有任何效果。 |
woocommerce_get_remove_url |
不支持 ❌ | 购物车块中的商品移除操作是异步处理的。 |
woocommerce_cart_item_remove_link |
不支持 ❌ | 购物车块中的商品移除操作是异步处理的。 |
woocommerce_cart_item_thumbnail |
不支持 ❌ | 这种方式修改缩略图不受支持。 请参阅 woocommerce_store_api_cart_item_images (PR Link 附带示例)。 |
woocommerce_cart_product_price |
不支持 ❌ | |
woocommerce_cart_item_price |
不支持 ❌ | |
woocommerce_quantity_input_classes |
不支持 ❌ | |
woocommerce_quantity_input_max |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_min |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_step |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_pattern |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_inputmode |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_placeholder |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_autocomplete |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_args |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_quantity_input_type |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_cart_item_quantity |
不支持 ❌ | 可以通过修改购物车项的 quantity_limits 属性,在 woocommerce_store_api_product_quantity_{$value_type} 过滤器中实现。 |
woocommerce_cart_product_subtotal |
不支持 ❌ | |
woocommerce_cart_item_subtotal |
不支持 ❌ | |
woocommerce_cross_sells_columns |
不支持 ❌ | 推荐商品以内部块的形式呈现。 |
woocommerce_cross_sells_orderby |
不支持 ❌ | 推荐商品以内部块的形式呈现。 |
woocommerce_cross_sells_order |
不支持 ❌ | 推荐商品以内部块的形式呈现。 |
woocommerce_cross_sells_total |
不支持 ❌ | 推荐商品以内部块的形式呈现。 |
woocommerce_product_cross_sells_products_heading |
不支持 ❌ | 可以在编辑器中进行修改。 |
woocommerce_is_downloadable |
不支持 ❌ | 在购物车/结账块中似乎没有任何效果。 |
woocommerce_loop_product_link |
不支持 ❌ | 在购物车块中,修改产品链接不受支持。 |
woocommerce_product_loop_title_classes |
不支持 ❌ | 在购物车块中,修改产品标题的类名不受支持。 |
woocommerce_product_add_to_cart_aria_describedby |
不支持 ❌ | 在购物车块中,修改产品 aria-describedby 属性不受支持。 |
woocommerce_sale_flash |
不支持 ❌ | 可以使用 saleBadgePriceFormat 结账过滤器 进行修改。 |
woocommerce_cart_subtotal |
不支持 ❌ | 在购物车/结账块中,修改购物车小计的显示不受支持。 |
oocommerce_shipping_package_details_array |
不支持 ❌ | 此 Hook 在购物车块渲染过程中不会被触发。 |
woocommerce_shipping_show_shipping_calculator |
不支持 ❌ | 仅在渲染购物车模板时使用,而块不使用模板。 |
woocommerce_cart_shipping_method_full_label |
不支持 ❌ | 此 Hook 在购物车/结账块中无效。 |
woocommerce_get_shipping_tax |
不支持 ❌ | 此过滤器在购物车/结账块中未使用。 |
woocommerce_shipping_calculator_enable_country |
不支持 ❌ | 此过滤器在购物车/结账块中未使用。 |
woocommerce_shipping_calculator_enable_state |
不支持 ❌ | 此过滤器在购物车/结账块中未使用。 |
woocommerce_shipping_calculator_enable_city |
不支持 ❌ | 此过滤器在购物车/结账块中未使用。 |
woocommerce_shipping_calculator_enable_postcode |
不支持 ❌ | 此过滤器在购物车/结账块中未使用。 |
woocommerce_cart_totals_fee_html |
不支持 ❌ | 在购物车/结账块中,修改费用显示不受支持。 |
woocommerce_countries_estimated_for_prefix |
不支持 ❌ | |
woocommerce_cart_total |
不支持 ❌ | 在购物车/结账块中,使用此 Hook 修改购物车总额不受支持。 |
woocommerce_cart_totals_order_total_html |
不支持 ❌ | 在购物车/结账块中,使用此 Hook 修改购物车总额不受支持。 |
术语表:
- Link: 链接
- Hook: 钩子
- API: API
- Placeholder: 占位符
- Rendering: 渲染
- Templates: 模板
- Download: 下载
- Quantity: 数量
- Subtotal: 小计
- Property: 属性
- Shipping: 配送
- Checkout: 结账
- Details: 详情
- Display: 显示
- Heading: 标题
- Product: 产品
- Enable: 启用
- Remove: 移除
- Images: 图像
- Format: 格式
结账 操作
本节描述与结账相关的操作。
重要提示: 在执行以下操作之前,请确保您已正确配置您的 Git 环境。
以下是一些常见的结账操作:
git checkout <commit>: 切换到指定的提交。git checkout <branch>: 切换到指定的分支。git checkout -b <new_branch>: 创建一个新的分支并切换到该分支。git checkout -- <file>: 取消对指定文件的修改,恢复到暂存区或 HEAD 的版本。git checkout .: 取消所有文件的修改,恢复到暂存区或 HEAD 的版本。
示例:
git checkout commit_id
说明:
<commit>: 要切换到的提交的哈希值或引用。<branch>: 要切换到的分支的名称。<new_branch>: 要创建的新分支的名称。<file>: 要取消修改的文件名。
警告:
- 结账操作可能会覆盖您本地的未提交更改。 在执行结账操作之前,请务必备份您的工作。
- 如果您的工作目录中有未提交的更改,并且您尝试切换到另一个分支,Git 可能会阻止您。 您可以使用
git stash命令来暂存您的更改,然后执行结账操作。
更多信息:
有关 git checkout 命令的更多信息,请参阅 git help checkout。
git checkout 命令的常用选项:
-n或--no-ornament:不要在输出中显示装饰。--detach:创建一个新的分支,但不要自动切换到该分支。-f或--force:强制执行结账操作,即使存在冲突。
git checkout 命令的常见错误:
error: Your local changes to the following files would be overwritten by checkout:: 您的本地更改会覆盖以下文件。error: Could not checkout '<branch>'. Branch '<branch>' does not exist.: 无法切换到 ''。 分支 '' 不存在。
git checkout 命令的替代方案:
git switch:一个更现代的切换分支的命令。git reset:一个用于重置工作目录和暂存区的命令。
总结:
git checkout 是一个强大的命令,可以用于在不同的提交、分支和工作目录状态之间进行切换。 但是,在使用 git checkout 命令时,请务必小心,因为它可能会覆盖您本地的未提交更改。
钩子兼容性列表
本表列出了 WooCommerce 钩子及其在 Cart/Checkout 块中的兼容性。
| 旧钩子 | 是否支持块? | 备注 |
|---|---|---|
woocommerce_before_checkout_form_cart_notices |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_before_checkout_form |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_before_customer_details |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_billing |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_before_checkout_billing_form |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_after_checkout_billing_form |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_shipping |
不支持 ❌ | 由于位置限制,没有直接对应的功能,但是 ExperimentalOrderShippingPackages 也许可以实现,或者可以在 "配送" 块中添加一个内部块。 |
woocommerce_before_checkout_shipping_form |
不支持 ❌ | 由于位置限制,没有直接对应的功能,但是 ExperimentalOrderShippingPackages 也许可以实现,或者可以在 "配送" 块中添加一个内部块。 |
woocommerce_after_checkout_shipping_form |
不支持 ❌ | 由于位置限制,没有直接对应的功能,但是 ExperimentalOrderShippingPackages 也许可以实现,或者可以在 "配送" 块中添加一个内部块。 |
woocommerce_before_order_notes |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_after_order_notes |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_after_customer_details |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_before_order_review_heading |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_before_order_review |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_order_review |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_before_cart_contents |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_after_cart_contents |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_before_shipping |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_after_shipping_rate |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_after_shipping |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_before_order_total |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_after_order_total |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_before_payment |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块或 "支付" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_before_terms_and_conditions |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_terms_and_conditions |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_after_terms_and_conditions |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_before_submit |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_after_submit |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_review_order_after_payment |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块或 "支付" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_after_order_review |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账订单摘要" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_after_checkout_form |
不支持 ❌ | 没有直接对应的功能,也没有可用的 Slot/fill 区域。 也许可以在 "结账字段" 块中添加一个内部块来实现,但位置需要由商家手动调整。 |
woocommerce_checkout_update_order_review |
不支持 ❌ | 此类 AJAX 事件在使用 Cart/Checkout 块时不会发生。 |
结账 筛选器
本节描述如何使用 筛选器 进行结账操作。
重要提示: 确保已正确配置您的系统,以便支持 筛选器。
以下是一些常见的结账流程:
-
准备商品: 确保所有需要结账的商品已添加到购物车。
-
应用筛选器: 使用
apply_filter()函数应用所需的 筛选器。例如:def apply_filter(filter_name, data): # 应用筛选器逻辑 return data -
计算总价: 使用
calculate_total()函数计算最终价格。def calculate_total(items, discounts): # 计算总价逻辑 return total_price -
确认订单: 确认订单信息,包括商品列表、总价和收货地址。
-
支付: 选择支付方式并完成支付。
-
结账: 完成结账流程。
示例:
# 示例代码
items = [
{"name": "商品A", "price": 10},
{"name": "商品B", "price": 20}
]
discounts = [
{"type": "优惠券", "amount": 5}
]
total_price = calculate_total(items, discounts)
print(f"总价: {total_price}")
常见问题:
- 如何添加新的 筛选器? 请参考 筛选器 开发文档。
- 为什么我的 筛选器 没有生效? 请检查 筛选器 的配置是否正确,以及是否已正确应用。
- 如何调试 筛选器? 可以使用
debug_filter()函数进行调试。
更多信息:
请使用 check 功能检查系统状态。
钩子支持状态
| 旧钩子 | 是否支持块? | 备注 |
|---|---|---|
woocommerce_add_notice |
部分支持 🔶 | 这些通知仅在“购物车”/“结账”块的页面加载时添加。如果在 API 请求期间发生的通知会被存储并在下一次完整的页面加载时显示。 |
woocommerce_checkout_coupon_message |
不支持 ❌ | 无法使用此过滤器自定义优惠券消息。 |
woocommerce_form_field_args |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field_text |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field_country |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field_state |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field_tel |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_form_field_email |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_cart_needs_shipping_address |
不支持 ❌ | 应使用 wc/store/cart 数据存储 来控制此项。 |
woocommerce_ship_to_different_address_checked |
不支持 ❌ | 应使用 wc/store/checkout 数据存储 来检查是否勾选了此复选框。 |
woocommerce_enable_order_notes_field |
不支持 ❌ | 此块必须在编辑器中删除,此过滤器不会影响其在“结账”块中的显示。 |
woocommerce_form_field_textarea |
不支持 ❌ | 尚未支持修改核心表单字段。 |
woocommerce_checkout_cart_item_visible |
不支持 ❌ | 无法从“购物车”/“结账”块的订单摘要中过滤购物车项目。 |
woocommerce_cart_item_class |
不支持 ❌ | 无法向“购物车”/“结账”块的订单摘要中的特定购物车项目添加类。 |
woocommerce_checkout_cart_item_quantity |
不支持 ❌ | 无法修改“购物车”/“结账”块的订单摘要中购物车项目的数量显示。 |
woocommerce_cart_product_subtotal |
不支持 ❌ | 不支持在“购物车”/“结账”块中修改产品小计的显示。 |
woocommerce_cart_item_subtotal |
不支持 ❌ | 不支持在“购物车”/“结账”块中修改产品小计的显示。 |
woocommerce_cart_subtotal |
不支持 ❌ | 不支持在“购物车”/“结账”块中修改购物车小计的显示。 |
woocommerce_cart_shipping_method_full_label |
不支持 ❌ | 不支持在“购物车”/“结账”块中修改配送方式的显示。 |
woocommerce_get_shipping_tax |
不支持 ❌ | 此过滤器不用于“购物车”/“结账”块。 |
woocommerce_cart_totals_fee_html |
不支持 ❌ | 不支持在“购物车”/“结账”块中修改费用显示。 |
woocommerce_cart_total |
不支持 ❌ | 不支持使用此钩子修改“购物车”/“结账”块中的购物车总计。 |
woocommerce_cart_totals_order_total_html |
不支持 ❌ | 不支持使用此钩子修改“购物车”/“结账”块中的订单总计 HTML - 请在编辑器中进行修改。 |
woocommerce_order_button_text |
不支持 ❌ | 不支持使用此钩子修改“购物车”/“结账”块中的订单按钮 HTML - 请在编辑器中进行修改。 |
woocommerce_gateway_title |
不支持 ❌ | 这些内容可以包含在与“购物车”/“结账”块注册的网关渲染的“内容”中,但无法通过 PHP 过滤器控制此项。 |
woocommerce_gateway_icon |
不支持 ❌ | 不显示网关图标。 它们可以包含在与“购物车”/“结账”块注册的网关渲染的“内容”中,但无法通过 PHP 过滤器控制此项。 |
woocommerce_gateway_description |
不支持 ❌ | 无法通过这种方式更改网关,网关需要使用 JavaScript 与“购物车”/“结账”块注册,并且第三方扩展无法修改这些前端详细信息。 |
woocommerce_checkout_show_terms |
不支持 ❌ | 此项无法通过此过滤器控制。 可以在编辑器中删除此块。 |
woocommerce_get_privacy_policy_text |
不支持 ❌ | 不支持使用此过滤器修改隐私政策文本。 可以在编辑器中进行修改。 |
woocommerce_order_button_html |
不支持 ❌ | 不支持使用此钩子修改“购物车”/“结账”块中的订单按钮 HTML - 请在编辑器中进行修改。 |
woocommerce_update_order_review_fragments |
不支持 ❌ | “购物车”/“结账”块不使用片段。 |
重要说明:
- Page: 网页
- Hook: 钩子
- API: API
- Privacy Policy: 隐私政策
- Form fields: 表单字段
- Extensions: 扩展
- Registered: 注册
- Checkbox: 复选框
- Quantity: 数量
- Register: 注册
- Subtotal: 小计
- Message: 信息
- Requests: 请求
- Shipping: 配送
- Checkout: 结账
- Address: 地址
- Details: 详情
- Privacy: 隐私
- Summary: 摘要
- Display: 显示
提交订单 操作
本部分正在进行中。
提交订单 筛选器
本部分正在进行中。
订单摘要 操作
本部分正在进行中。
订单摘要 筛选器
本部分正在进行中。
常见的扩展方式
购物车和结账模块
完全支持,无需修改
- 修改购物车中的费用和其他价格 (
woocommerce_cart_calculate_fees) - 在 WC 生命周期事件期间更新客户信息,例如在
woocommerce_init中,更新客户的地址会反映在购物车/结账模块中。 - 添加付款方式
- 使用
woocommerce_product_get_name更改产品名称
部分支持或通过替代方法支持
- 修改布局,例如在特定部分(如配送、付款以及账单/配送地址)之前/之后插入内容。例如:在各种位置输出内容,例如在打印购物车内容之前 (
woocommerce_cart_contents) 和在显示运费之前 (woocommerce_before_shipping_rate):- 这通过我们的 Slot/Fill 功能以及通过将内部块注册为要显示的块的子块来实现。
- 添加付款方式
- 仅仅添加付款方式是不够的,开发者还需要注册一个 React 组件,以便在付款模块中显示。
- 添加本地自提的配送方式
- 应该可以正常工作,但需要该方式支持本地自提功能。
- 修改购物车中商品的名称
- 需要开发者使用 JavaScript 筛选器,而不是 PHP 筛选器。
完全不支持
- 修改单个购物车项目以添加或更改内容/更改 HTML(超出我们结账筛选器提供的范围)。
结账模块
完全支持,无需修改
- 预填充表单中的值(一些商家通过覆盖其值来实现,使用
woocommerce_checkout_get_value)- 只要购物车/客户对象中设置的值,我们都会尊重这些值。
woocommerce_checkout_get_value不在结账模块中支持,但这是该钩子的唯一用例。
- 只要购物车/客户对象中设置的值,我们都会尊重这些值。
部分支持或通过替代方法实现
- 添加新的结账字段(通常通过
woocommerce_checkout_fields钩子实现)- 通过附加结账字段 API 支持,但目前并非所有字段类型都受支持。
- 使用钩子(如
woocommerce_checkout_process)进行自定义字段验证- 通过钩入支付处理事件支持,验证发生在点击“提交订单”时,这仅适用于付款方式。其他扩展可以在点击按钮之前将验证错误添加到数据存储中,从而阻止结账,但这并不是一个好的解决方案,尤其是在验证检查成本较高的情况下。
- 在订单提交之前/期间/之后更新订单/客户(通过钩子实现)
- 我们有一些在结账过程中触发的钩子:
woocommerce_store_api_checkout_order_processed- 订单已提交时触发。woocommerce_store_api_checkout_update_customer_from_request- 当客户数据从结账请求中更新时触发。woocommerce_store_api_checkout_update_order_meta- 当订单元数据从请求中更新时触发。
- 任何其他在短代码过程中触发的 WC 钩子(例如
woocommerce_checkout_order_processed)不会在块中的 Store API 请求中触发。
- 我们有一些在结账过程中触发的钩子:
- 使用
woocommerce_order_button_text自定义“提交订单”按钮文本- 不支持通过钩子实现,但可以在编辑器中实现。目前没有编程方式可以实现此功能。
完全不支持
- 修改现有的核心字段(通常通过
woocommerce_checkout_fields钩子实现) - 移除账单/配送地址(使用上述方法)
- 在订单最终确定之前执行操作 (
woocommerce_checkout_create_order)
购物车块
完全支持,无需任何修改
- 无,这些内容已经在“两个块”部分中涵盖。
部分支持或通过替代方法实现
- 限制购物车中商品的数量选择,例如设置最小值、最大值或步长值。 以前,这通常通过过滤器(如
woocommerce_quantity_input_step)来实现。- 可以通过修改购物车项的
quantity_limits属性,在woocommerce_store_api_product_quantity_{$value_type}过滤器中实现。
- 可以通过修改购物车项的
完全不支持
- 通过修改模板文件来修改布局(除非使用块主题和自定义模板)
迁移的旧版钩子
以下是存在于 WooCommerce 核心代码中,并被迁移到 WooCommerce Blocks 的钩子。
请注意,这里的操作和筛选器在服务器端运行。客户端区块的更改不一定基于添加到服务器端钩子的回调函数。 请参阅我们关于在客户端操作区块的 API 的说明文档。
遗留筛选器
本节描述了旧版本的筛选器。
重要提示: 建议使用新的筛选器 API,因为它提供了更好的性能和更灵活的配置选项。
以下是旧筛选器的详细信息:
filter_name_1: 用于执行特定类型的筛选操作。- 参数:
param1(类型: %s, 描述: 描述参数1),param2(类型: %d, 描述: 描述参数2) - 返回值:
result(类型: 描述结果类型)
- 参数:
filter_name_2: 用于执行另一种类型的筛选操作。- 参数:
param3(类型: 字符串, 描述: 描述参数3) - 返回值:
success(类型: 布尔值, 描述: 表示操作是否成功)
- 参数:
示例:
# 使用 filter_name_1
result = filter_name_1(param1="value1", param2=123)
print(result)
# 使用 filter_name_2
success = filter_name_2(param3="some_string")
if success:
print("操作成功")
else:
print("操作失败")
注意事项:
- 旧筛选器可能存在性能问题。
- 旧筛选器可能不支持所有新的功能。
- 建议升级到新的筛选器 API。
有关新筛选器 API 的更多信息,请访问 https://example.com/new_filters。
错误处理:
如果出现错误,旧筛选器可能会引发以下异常:
FilterError: 表示筛选器执行过程中出现错误。ParameterError: 表示参数无效。
配置:
旧筛选器的配置选项通常位于配置文件 {config_file} 中。 请参阅配置文件格式的详细说明。
已知问题:
- 在某些情况下,
filter_name_1可能会导致内存泄漏。 filter_name_2在处理非常大的字符串时可能会变得非常慢。
替代方案:
如果无法升级到新的筛选器 API,可以考虑使用以下替代方案:
- 编写自定义筛选器。
- 使用第三方筛选器库。
联系方式:
如果您有任何问题或需要进一步的帮助,请联系 support@example.com。
WooCommerce 扩展性:钩子 (Hooks)
本页面面向 开发者,介绍了如何通过 钩子 来自定义 WooCommerce 的行为。
过滤器 (Filters)
以下是一些常用的过滤器:
- loop_shop_per_page: 每页商品数量。
- wc_session_expiration: 会话过期时间。
- woocommerce_add_cart_item: 添加商品到购物车。
- woocommerce_add_cart_item_data: 添加商品到购物车的数据。
- woocommerce_add_to_cart_quantity: 添加到购物车商品的数量。
- woocommerce_add_to_cart_sold_individually_quantity: 单个销售商品的添加到购物车数量。
- woocommerce_add_to_cart_validation: 添加到购物车验证。
- woocommerce_adjust_non_base_location_prices: 调整非基础位置的价格。
- woocommerce_apply_base_tax_for_local_pickup: 为本地自提应用基础税。
- woocommerce_apply_individual_use_coupon: 应用单个使用优惠券。
- woocommerce_apply_with_individual_use_coupon: 使用单个使用优惠券应用。
- woocommerce_cart_contents_changed: 购物车内容发生变化。
- woocommerce_cart_item_permalink: 购物车商品固定链接。
- woocommerce_get_item_data: 获取商品数据。
- woocommerce_loop_add_to_cart_args: 循环中添加到购物车的参数。
- woocommerce_loop_add_to_cart_link: 循环中添加到购物车的链接。
- woocommerce_new_customer_data: 新客户数据。
- woocommerce_pay_order_product_has_enough_stock: 支付订单时,商品库存是否充足。
- woocommerce_pay_order_product_in_stock: 支付订单时,商品是否在库存中。
- woocommerce_registration_errors: 注册错误。
- woocommerce_shipping_package_name: 配送包裹名称。
- woocommerce_show_page_title: 显示页面标题。
- woocommerce_single_product_image_thumbnail_html: 单个商品图片缩略图 HTML。
重要提示: 请仔细阅读每个钩子的文档,了解其用法和参数。 不正确的用法可能导致 错误 或意外的行为。 确保你的代码 有效,并且不会影响其他插件或主题的功能。 在修改任何 数据 之前,请务必进行备份。 通过使用这些钩子,你可以自定义 产品 的显示方式、订单 处理流程、注册 流程以及其他 WooCommerce 的核心功能。 请注意,某些钩子可能需要 WooCommerce 的特定版本才能正常工作。 在进行任何更改之前,请检查 WooCommerce 的官方文档以获取最新的信息。 如果遇到问题,请参考 WooCommerce 的 帮助 文档或联系 支持 团队。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过合理地使用这些钩子,你可以扩展 WooCommerce 的功能,并为你的用户提供更好的购物体验。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 链接 的行为、内容 的显示方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 位置 的显示方式、数量 的计算方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 标题 的显示方式、库存 的管理方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 会话 的管理方式、优惠券 的使用方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 配送 的方式、页面 的显示方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 验证 的流程、注册 的方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 数据 的处理方式、内容 的显示方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 链接 的行为、内容 的显示方式以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。 通过这些钩子,你可以自定义 产品 的显示方式、订单 的处理流程以及其他 WooCommerce 的核心功能。 请记住,良好的代码实践和充分的测试对于确保你的自定义功能的稳定性和可靠性至关重要。 通过这些钩子,你可以创建高度定制化的 WooCommerce 商店,以满足你的特定需求。 请注意,某些钩子可能与第三方插件或主题冲突,因此在进行任何更改之前,请务必进行测试。
遗留的操作
- woocommerce_add_to_cart
- woocommerce_after_main_content
- woocommerce_after_shop_loop
- woocommerce_applied_coupon
- woocommerce_archive_description
- woocommerce_before_main_content
- woocommerce_before_shop_loop
- woocommerce_check_cart_items
- woocommerce_created_customer
- woocommerce_no_products_found
- woocommerce_register_post
- woocommerce_shop_loop
Hook alternatives
These are the hooks that run when loading the Cart/Checkout shortcodes and blocks. Some are general WooCommerce lifecycle hooks, some are specific to the Cart and Checkout pages. These were generated by logging each call to do_action and apply_filters and reviewing the issues mentioning "hooks" and "filter(s)" in the old WooCommerce Blocks repository.
Legend
| Icon | Description |
|---|---|
| ✅ | Fully supported |
| 🔶 | Partially supported |
| ❌ | Not supported |
| ❓ | Unknown |
If a hook is marked as Unknown ❓(Unknown) it means we were not able to verify whether the hook is supported for some reason. As time goes on, we will attempt to validate more of these hooks. The goal is to have no hooks with an Unknown ❓status remaining in any of the tables.
WooCommerce lifecycle actions
These hooks run on every Woo page load, some affect the blocks, some don't, some only affect them partially.
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_load_cart_from_session |
Fully supported ✅ | |
woocommerce_cart_loaded_from_session |
Fully supported ✅ | |
woocommerce_set_cart_cookies |
Fully supported ✅ | |
woocommerce_shipping_zone_loaded |
Fully supported ✅ | |
woocommerce_check_cart_items |
Fully supported ✅ | May be better to use woocommerce_store_api_validate_cart_item |
woocommerce_before_calculate_totals |
Fully supported ✅ | |
woocommerce_shipping_init |
Fully supported ✅ | |
woocommerce_load_shipping_methods |
Fully supported ✅ | |
woocommerce_cart_calculate_fees |
Fully supported ✅ | |
woocommerce_calculate_totals |
Fully supported ✅ | |
woocommerce_after_calculate_totals |
Fully supported ✅ | |
woocommerce_cart_updated |
Fully supported ✅ | |
woocommerce_before_get_rates_for_package |
Fully supported ✅ | |
woocommerce_after_get_rates_for_package |
Fully supported ✅ | |
woocommerce_checkout_init |
Fully supported ✅ | |
woocommerce_customer_loaded |
Fully supported ✅ |
WooCommerce lifecycle filters
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_notice_types |
Unknown ❓ | WC Blocks does not handle additional notice types outside of the core ones. Non-supported notices would be displayed as "info" notices. |
woocommerce_kses_notice_allowed_tags |
Unknown ❓ | |
woocommerce_product_get_stock_status |
Fully supported ✅ | |
woocommerce_product_is_in_stock |
Fully supported ✅ | |
woocommerce_product_get_manage_stock |
Unknown ❓ | |
woocommerce_product_get_tax_class |
Fully supported ✅ | |
woocommerce_product_get_tax_status |
Unknown ❓ | |
woocommerce_prices_include_tax |
Unknown ❓ | |
woocommerce_apply_base_tax_for_local_pickup |
Unknown ❓ | |
woocommerce_local_pickup_methods |
Not supported ❌ | Does not affect the blocks-based local pickup methods |
woocommerce_customer_get_shipping_postcode |
Fully supported ✅ | |
woocommerce_customer_get_shipping_city |
Fully supported ✅ | |
woocommerce_customer_taxable_address |
Unknown ❓ | |
woocommerce_shipping_methods |
Fully supported ✅ | |
woocommerce_format_localized_price |
Unknown ❓ | |
woocommerce_shipping_local_pickup_option |
Not supported ❌ | Does not affect the blocks-based local pickup methods |
woocommerce_shipping_pickup_location_option |
Unknown ❓ | Unsure if changing this changes the way local pickup shows in the Cart/Checkout |
woocommerce_shipping_method_supports |
Fully supported ✅ | |
woocommerce_get_tax_location |
Unknown ❓ | |
woocommerce_format_postcode |
Unknown ❓ | |
woocommerce_matched_tax_rates |
Unknown ❓ | |
woocommerce_find_rates |
Unknown ❓ | |
woocommerce_matched_rates |
Unknown ❓ | |
woocommerce_cart_totals_get_item_tax_rates |
Fully supported ✅ | |
woocommerce_adjust_non_base_location_prices |
Unknown ❓ | |
woocommerce_product_is_taxable |
Fully supported ✅ | |
woocommerce_price_ex_tax_amount |
Fully supported ✅ | |
woocommerce_tax_round |
Fully supported ✅ | |
woocommerce_calc_tax |
Fully supported ✅ | |
woocommerce_calculate_item_totals_taxes |
Fully supported ✅ | |
woocommerce_cart_ready_to_calc_shipping |
Fully supported ✅ | |
woocommerce_product_get_virtual |
Fully supported ✅ | |
woocommerce_is_virtual |
Fully supported ✅ | |
woocommerce_product_needs_shipping |
Fully supported ✅ | |
woocommerce_cart_needs_shipping |
Fully supported ✅ | |
woocommerce_customer_get_shipping_address_1 |
Fully supported ✅ | |
woocommerce_customer_get_shipping_address_2 |
Fully supported ✅ | |
woocommerce_cart_display_prices_including_tax |
Fully supported ✅ | |
woocommerce_cart_get_subtotal |
Fully supported ✅ | |
woocommerce_cart_shipping_packages |
Fully supported ✅ | |
woocommerce_product_get_shipping_class_id |
Fully supported ✅ | |
woocommerce_countries_shipping_countries |
Fully supported ✅ | |
woocommerce_get_zone_criteria |
Fully supported ✅ | |
woocommerce_shipping_zone_shipping_methods |
Fully supported ✅ | |
woocommerce_shipping_free_shipping_is_available |
Unknown ❓ | |
woocommerce_product_get_name |
Fully supported ✅ | |
woocommerce_shipping_method_add_rate |
Fully supported ✅ | |
woocommerce_shipping_flat_rate_is_available |
Fully supported ✅ | |
woocommerce_evaluate_shipping_cost_args |
Fully supported ✅ | |
woocommerce_calc_shipping_tax |
Fully supported ✅ | |
woocommerce_localisation_address_formats |
Fully supported ✅ | |
woocommerce_countries_base_country |
Unknown ❓ | |
woocommerce_formatted_address_force_country_display |
Unknown ❓ | |
woocommerce_states |
Fully supported ✅ | |
woocommerce_formatted_address_replacements |
Unknown ❓ | |
woocommerce_package_rates |
Fully supported ✅ | |
woocommerce_shipping_packages |
Fully supported ✅ | |
woocommerce_shipping_rate_method_id |
Fully supported ✅ | |
woocommerce_shipping_rate_taxes |
Fully supported ✅ | |
woocommerce_shipping_rate_cost |
Fully supported ✅ | |
woocommerce_cart_totals_get_fees_from_cart_taxes |
Fully supported ✅ | |
woocommerce_calculated_total |
Not supported ❌ | This does not seem to have any effect |
woocommerce_cart_get_discount_total |
Fully supported ✅ | |
woocommerce_cart_get_cart_contents_total |
Fully supported ✅ | |
woocommerce_get_price_excluding_tax |
Not supported ❌ | This does not seem to have any effect |
raw_woocommerce_price |
Not supported ❌ | This does not seem to have any effect |
formatted_woocommerce_price |
Not supported ❌ | This does not seem to have any effect |
woocommerce_price_trim_zeros |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_cart_page_permalink |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_cart_url |
Not supported ❌ | This does not seem to have any effect |
woocommerce_checkout_registration_enabled |
Fully supported ✅ | This does not seem to have any effect |
woocommerce_get_checkout_page_permalink |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_checkout_url |
Not supported ❌ | This does not seem to have any effect |
woocommerce_checkout_get_value |
Not supported ❌ | This does not seem to have any effect |
woocommerce_default_address_fields |
Not supported ❌ | This does not seem to have any effect |
default_checkout_billing_country |
Not supported ❌ | This does not seem to have any effect |
default_checkout_shipping_country |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_country_locale |
Fully supported ✅ | |
woocommerce_get_country_locale_default |
Unknown ❓ | |
woocommerce_get_country_locale_base |
Unknown ❓ | |
woocommerce_billing_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_shipping_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_checkout_fields |
Partially supported 🔶 | Editing core fields is not supported, but adding them is via Additional Checkout Fields API |
woocommerce_cart_item_product |
Not supported ❌ | Modifying individual cart items is not possible |
woocommerce_payment_gateway_supports |
Fully supported ✅ | |
woocommerce_customer_get_billing_first_name |
Fully supported ✅ | |
woocommerce_customer_get_billing_last_name |
Fully supported ✅ | |
woocommerce_customer_get_billing_company |
Fully supported ✅ | |
woocommerce_customer_get_billing_address_1 |
Fully supported ✅ | |
woocommerce_customer_get_billing_address_2 |
Fully supported ✅ | |
woocommerce_customer_get_billing_city |
Fully supported ✅ | |
woocommerce_customer_get_billing_postcode |
Fully supported ✅ | |
woocommerce_customer_get_billing_phone |
Fully supported ✅ | |
woocommerce_customer_get_shipping_first_name |
Fully supported ✅ | |
woocommerce_customer_get_shipping_last_name |
Fully supported ✅ | |
woocommerce_customer_get_shipping_company |
Fully supported ✅ | |
woocommerce_get_item_data |
Partially supported 🔶 | Checkout blocks strip most HTML from metadata, allowing only a, b, em, i, strong, br, abbr, and span. |
woocommerce_cart_get_subtotal_tax |
Not supported ❌ | This does not seem to have any effect |
woocommerce_shipping_package_name |
Fully supported ✅ | |
woocommerce_shipping_rate_id |
Unknown ❓ | |
woocommerce_shipping_rate_label |
Fully supported ✅ | |
woocommerce_cart_get_shipping_taxes |
Fully supported ✅ | |
woocommerce_cart_get_fee_taxes |
Fully supported ✅ | |
woocommerce_cart_get_taxes |
Fully supported ✅ | |
woocommerce_rate_code |
Unknown ❓ | |
woocommerce_rate_compound |
Unknown ❓ | |
woocommerce_rate_label |
Fully supported ✅ | |
woocommerce_cart_hide_zero_taxes |
Unknown ❓ | |
woocommerce_cart_tax_totals |
Fully supported ✅ | |
woocommerce_cart_needs_payment |
Fully supported ✅ | |
woocommerce_order_class |
Fully supported ✅ | |
woocommerce_checkout_registration_required |
Unknown ❓ | |
woocommerce_privacy_policy_page_id |
Fully supported ✅ | |
woocommerce_get_terms_page_id |
Unknown ❓ | |
woocommerce_terms_and_conditions_page_id |
Unknown ❓ | |
woocommerce_cart_contents_count |
Unknown ❓ | |
woocommerce_country_locale_field_selectors |
Not supported ❌ | |
woocommerce_get_return_url |
Fully supported ✅ | |
woocommerce_cart_hash |
Fully supported ✅ | |
woocommerce_cart_get_fee_tax |
Fully supported ✅ | |
woocommerce_customer_default_location_array |
Fully supported ✅ | |
woocommerce_countries |
Fully supported ✅ | |
woocommerce_sort_countries |
Not supported ❌ | This does not seem to have any effect |
woocommerce_countries_allowed_countries |
Fully supported ✅ | |
woocommerce_customer_default_location_array |
Fully supported ✅ | |
woocommerce_customer_get_billing_country |
Fully supported ✅ | |
woocommerce_customer_get_shipping_country |
Fully supported ✅ | |
woocommerce_customer_get_billing_state |
Fully supported ✅ | |
woocommerce_customer_get_shipping_state |
Fully supported ✅ | |
woocommerce_customer_get_billing_email |
Fully supported ✅ | |
woocommerce_cart_session_initialize |
Fully supported ✅ | |
woocommerce_get_checkout_page_id |
Fully supported ✅ | |
woocommerce_get_cart_page_id |
Fully supported ✅ | |
woocommerce_is_checkout |
Fully supported ✅ | |
woocommerce_currency |
Fully supported ✅ | |
woocommerce_currency_symbols |
Fully supported ✅ | |
woocommerce_currency_symbol |
Fully supported ✅ | |
woocommerce_price_format |
Fully supported ✅ | |
woocommerce_coupons_enabled |
Fully supported ✅ | |
woocommerce_get_shop_page_id |
Fully supported ✅ | |
current_theme_supports-woocommerce |
Fully supported ✅ | |
woocommerce_payment_gateways |
Partially supported 🔶 | Integration with WC Blocks is still required, beyond unsetting gateways, manipulating the payment gateways here may not work in the Cart and Checkout blocks |
woocommerce_get_base_location |
Fully supported ✅ | |
woocommerce_gateway_icon |
Not supported ❌ | This hook has no effect since icons are not displayed. |
woocommerce_get_image_size_thumbnail |
Fully supported ✅ | |
woocommerce_get_image_size_single |
Fully supported ✅ | |
woocommerce_product_stock_status_options |
Fully supported ✅ | |
woocommerce_cart_item_name |
Not supported ❌ | Use the itemName checkout filter. |
woocommerce_product_get_status |
Fully supported ✅ | |
woocommerce_product_get_price |
Fully supported ✅ | |
woocommerce_is_purchasable |
Fully supported ✅ | |
woocommerce_cart_item_is_purchasable |
Fully supported ✅ | |
woocommerce_cart_item_data_to_validate |
Fully supported ✅ | |
woocommerce_get_cart_item_from_session |
Fully supported ✅ | |
woocommerce_cart_contents_changed |
Fully supported ✅ | |
woocommerce_get_cart_contents |
Fully supported ✅ | |
woocommerce_stock_amount |
Fully supported ✅ | |
woocommerce_cart_item_remove_link |
Not supported ❌ | Use the showRemoveItemLink checkout filter. |
woocommerce_cart_item_quantity |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_product_get_image |
Not supported ❌ | Use woocommerce_store_api_cart_item_images (PR Link with example.) |
woocommerce_cart_no_shipping_available_html |
Not supported ❌ | This is not editable |
woocommerce_available_payment_gateways |
Partially supported 🔶 | Integration with WC Blocks is still required, beyond unsetting gateways, manipulating the payment gateways here may not work in the Cart and Checkout blocks |
woocommerce_cart_get_total |
Fully supported ✅ | |
woocommerce_cart_get_fee_tax |
Fully supported ✅ | |
woocommerce_cart_get_cart_contents_tax |
Fully supported ✅ | |
woocommerce_cart_get_shipping_tax |
Fully supported ✅ | |
woocommerce_cart_get_shipping_total |
Fully supported ✅ |
Cart actions
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_before_cart |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. It is also possible to use the render_block_{$name} filter to render before and after blocks using PHP. |
woocommerce_before_cart_table |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_before_cart_contents |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_cart_item_name |
Not supported ❌ | Use the itemName checkout filter. |
woocommerce_before_quantity_input_field |
Not supported ❌ | No equivalent now. |
woocommerce_after_quantity_input_field |
Not supported ❌ | No equivalent now. |
woocommerce_cart_contents |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_cart_coupon |
Not supported ❌ | ExperimentalDiscountsMeta slot/fill |
woocommerce_cart_actions |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_after_cart_contents |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_cart_table |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_before_cart_collaterals |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_cart_collaterals |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_before_cart_totals |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_cart_totals_before_shipping |
Not supported ❌ | ExperimentalOrderShippingPackages |
woocommerce_after_shipping_rate |
Not supported ❌ | ExperimentalOrderShippingPackages |
woocommerce_before_shipping_calculator |
Not supported ❌ | No specific equivalent. Closest thing is ExperimentalOrderShippingPackages |
woocommerce_after_shipping_calculator |
Not supported ❌ | No specific equivalent. Closest thing is ExperimentalOrderShippingPackages |
woocommerce_cart_totals_after_shipping |
Not supported ❌ | No specific equivalent. Closest thing is ExperimentalOrderShippingPackages |
woocommerce_cart_totals_before_order_total |
Not supported ❌ | No specific equivalent but we do have the totals footer item filters |
woocommerce_cart_totals_after_order_total |
Not supported ❌ | No specific equivalent but we do have the totals footer item filters |
woocommerce_proceed_to_checkout |
Not supported ❌ | No specific equivalent but the Checkout and Place Order button filters may work |
woocommerce_after_cart_totals |
Not supported ❌ | ExperimentalOrderMeta slot/fill |
woocommerce_after_cart |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Cart items" block could work, but it would have to be positioned manually by the merchant. |
Cart filters
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_cart_item_product_id |
Not supported ❌ | This does not seem to have any effect |
woocommerce_cart_item_visible |
Not supported ❌ | This does not seem to have any effect |
woocommerce_get_remove_url |
Not supported ❌ | The removal of items is handled async in the Cart block. |
woocommerce_cart_item_remove_link |
Not supported ❌ | The removal of items is handled async in the Cart block. |
woocommerce_cart_item_thumbnail |
Not supported ❌ | Changing the thumbnail this way is not supported. See woocommerce_store_api_cart_item_images (PR Link with example.) |
woocommerce_cart_product_price |
Not supported ❌ | |
woocommerce_cart_item_price |
Not supported ❌ | |
woocommerce_quantity_input_classes |
Not supported ❌ | |
woocommerce_quantity_input_max |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_min |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_step |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_pattern |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_inputmode |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_placeholder |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_autocomplete |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_args |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_quantity_input_type |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_cart_item_quantity |
Not supported ❌ | This is possible by modifying the quantity_limits property of the cart item in the woocommerce_store_api_product_quantity_{$value_type} filter. |
woocommerce_cart_product_subtotal |
Not supported ❌ | |
woocommerce_cart_item_subtotal |
Not supported ❌ | |
woocommerce_cross_sells_columns |
Not supported ❌ | The cross sells are rendered as an inner block. |
woocommerce_cross_sells_orderby |
Not supported ❌ | The cross sells are rendered as an inner block. |
woocommerce_cross_sells_order |
Not supported ❌ | The cross sells are rendered as an inner block. |
woocommerce_cross_sells_total |
Not supported ❌ | The cross sells are rendered as an inner block. |
woocommerce_product_cross_sells_products_heading |
Not supported ❌ | This can be modified in the editor. |
woocommerce_is_downloadable |
Not supported ❌ | Does not seem to have any effect in Cart/Checkout blocks. |
woocommerce_loop_product_link |
Not supported ❌ | Changing the product links is not supported in the Cart block. |
woocommerce_product_loop_title_classes |
Not supported ❌ | Changing classes to product titles is not supported in the Cart block. |
woocommerce_product_add_to_cart_aria_describedby |
Not supported ❌ | Changing aria-describedby on products is not supported in the Cart block. |
woocommerce_sale_flash |
Not supported ❌ | This can be modified with the saleBadgePriceFormat checkout filter. |
woocommerce_cart_subtotal |
Not supported ❌ | Modifying the cart subtotal display is not supported in the Cart/Checkout blocks |
oocommerce_shipping_package_details_array |
Not supported ❌ | This hook is not fired during Cart block rendering |
woocommerce_shipping_show_shipping_calculator |
Not supported ❌ | This is only used when rendering cart templates, which does not happen in the blocks. |
woocommerce_cart_shipping_method_full_label |
Not supported ❌ | This hook has no effect in the Cart/Checkout blocks. |
woocommerce_get_shipping_tax |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_shipping_calculator_enable_country |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_shipping_calculator_enable_state |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_shipping_calculator_enable_city |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_shipping_calculator_enable_postcode |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_cart_totals_fee_html |
Not supported ❌ | Modifying the fees display is not supported in the Cart/Checkout blocks |
woocommerce_countries_estimated_for_prefix |
Not supported ❌ | |
woocommerce_cart_total |
Not supported ❌ | Modifying the cart total using this hook is not supported in the Cart/Checkout blocks |
woocommerce_cart_totals_order_total_html |
Not supported ❌ | Modifying the cart total using this hook is not supported in the Cart/Checkout blocks |
Checkout actions
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_before_checkout_form_cart_notices |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_before_checkout_form |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_before_customer_details |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_billing |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_before_checkout_billing_form |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_checkout_billing_form |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_shipping |
Not supported ❌ | Not directly equivalent due to positioning, but ExperimentalOrderShippingPackages could work - so could adding an inner block to the shipping block |
woocommerce_before_checkout_shipping_form |
Not supported ❌ | Not directly equivalent due to positioning, but ExperimentalOrderShippingPackages could work - so could adding an inner block to the shipping block |
woocommerce_after_checkout_shipping_form |
Not supported ❌ | Not directly equivalent due to positioning, but ExperimentalOrderShippingPackages could work - so could adding an inner block to the shipping block |
woocommerce_before_order_notes |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_order_notes |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_after_customer_details |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_before_order_review_heading |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_before_order_review |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_order_review |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_before_cart_contents |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_after_cart_contents |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_before_shipping |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_shipping_rate |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_after_shipping |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_before_order_total |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_after_order_total |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_before_payment |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block or Payment block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_before_terms_and_conditions |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_terms_and_conditions |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_after_terms_and_conditions |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_before_submit |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_after_submit |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_review_order_after_payment |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block or Payment block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_after_order_review |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Order Summary" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_after_checkout_form |
Not supported ❌ | No specific equivalent and no Slot/fill for this area. Maybe adding an inner block to the "Checkout Fields" block could work, but it would have to be positioned manually by the merchant. |
woocommerce_checkout_update_order_review |
Not supported ❌ | These type of AJAX events do not occur when using the Cart/Checkout blocks |
Checkout filters
| Old hook | Works in blocks? | Notes |
|---|---|---|
woocommerce_add_notice |
Partially supported 🔶 | These notices are only added on page load of the Cart/Checkout blocks. Any that happen during API requests are stored and output on the next full page load. |
woocommerce_checkout_coupon_message |
Not supported ❌ | The coupon message cannot be customised using this filter. |
woocommerce_form_field_args |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field_text |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field_country |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field_state |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field_tel |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_form_field_email |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_cart_needs_shipping_address |
Not supported ❌ | The wc/store/cart data store should be used to control this. |
woocommerce_ship_to_different_address_checked |
Not supported ❌ | The wc/store/checkout data store should be used to check if this checkbox is checked. |
woocommerce_enable_order_notes_field |
Not supported ❌ | This block must be removed in the editor, this filter will not affect its presence in the Checkout block |
woocommerce_form_field_textarea |
Not supported ❌ | Modifying core form fields is not supported yet in the Cart/Checkout blocks. |
woocommerce_checkout_cart_item_visible |
Not supported ❌ | It is not possible to filter cart items from the order summary in the Cart/Checkout blocks. |
woocommerce_cart_item_class |
Not supported ❌ | It is not possible to add classes to specific cart items in the order summary in the Cart/Checkout blocks. |
woocommerce_checkout_cart_item_quantity |
Not supported ❌ | It is not possible to modify the quantity display of cart items in the order summary in the Cart/Checkout blocks. |
woocommerce_cart_product_subtotal |
Not supported ❌ | Modifying the product subtotal display is not supported in the Cart/Checkout blocks |
woocommerce_cart_item_subtotal |
Not supported ❌ | Modifying the product subtotal display is not supported in the Cart/Checkout blocks |
woocommerce_cart_subtotal |
Not supported ❌ | Modifying the cart subtotal display is not supported in the Cart/Checkout blocks |
woocommerce_cart_shipping_method_full_label |
Not supported ❌ | Modifying the shipping method display is not supported in the Cart/Checkout blocks |
woocommerce_get_shipping_tax |
Not supported ❌ | This filter is not used in the Cart/Checkout blocks. |
woocommerce_cart_totals_fee_html |
Not supported ❌ | Modifying the fees display is not supported in the Cart/Checkout blocks |
woocommerce_cart_total |
Not supported ❌ | Modifying the cart total using this hook is not supported in the Cart/Checkout blocks |
woocommerce_cart_totals_order_total_html |
Not supported ❌ | Modifying the order total html using this hook is not supported in the Cart/Checkout blocks - edit it using the editor. |
woocommerce_order_button_text |
Not supported ❌ | Modifying the order button html using this hook is not supported in the Cart/Checkout blocks - edit it using the editor. |
woocommerce_gateway_title |
Not supported ❌ | These can be included in the "Content" rendered by gateways registered with the Cart/Checkout block but it is not possible to control this via PHP filters. |
woocommerce_gateway_icon |
Not supported ❌ | Gateway icons are not shown. They can be included in the "Content" rendered by gateways registered with the Cart/Checkout block but it is not possible to control this via PHP filters. |
woocommerce_gateway_description |
Not supported ❌ | Changing gateways this way is not possible, gateways need to register with the Cart/Checkout blocks using JavaScript and third party extensions can't modify these front-end details. |
woocommerce_checkout_show_terms |
Not supported ❌ | This is not controllable via this filter. The block can be removed in the editor. |
woocommerce_get_privacy_policy_text |
Not supported ❌ | Modifying the privacy policy text using this filter is not supported. It can be modified in the editor. |
woocommerce_order_button_html |
Not supported ❌ | Modifying the order button html using this hook is not supported in the Cart/Checkout blocks - edit it using the editor. |
woocommerce_update_order_review_fragments |
Not supported ❌ | Fragments are not used on the Cart/Checkout blocks. |
Place order actions
This section is a work in progress.
Place order filters
This section is a work in progress.
Order summary actions
This section is a work in progress.
Order summary filters
This section is a work in progress.
Common extensibility paths
Cart and Checkout blocks
Fully supported with no modification needed
- Modifying fees and other prices on the cart (
woocommerce_cart_calculate_fees) - Updating customer information during the WC lifecycle events, e.g. on
woocommerce_init, updating a customer's address would reflect in the Cart/Checkout blocks. - Adding Shipping methods
- Changing product names using woocommerce_product_get_name
Partially supported or supported by alternative approach
- Modifying the layout, e.g. inserting content before/after specific sections such as shipping, payment, and the billing/shipping addresses. Examples include: Outputting content in various places, e.g. before the cart contents are printed (
woocommerce_cart_contents) and before the shipping rates (woocommerce_before_shipping_rate):- This is supported by our use of Slot/Fill and by registering inner blocks as children of the block you want to show them after.
- Adding payment methods
- Simply adding the payment method is not enough, developers need to register a React component to show in the payments block as well.
- Adding shipping methods for local pickup
- Should work as normal, but does require the method to support collectable
- Modify the names of items in the cart
- Requires the developer to use a JS filter rather than PHP filter
Not supported at all
- Modifying individual cart line items to add or change content/change HTML (outside of what is offered by our checkout filters).
Checkout block
Fully supported with no modification needed
- Pre-filling values on the form (Some merchants achieve this by overriding their values using
woocommerce_checkout_get_value)- This is supported insofar as we respect what has been set on the cart/customer object when loading the cart.
woocommerce_checkout_get_valueis not supported in the Checkout block, but this is this hooks only use-case.
- This is supported insofar as we respect what has been set on the cart/customer object when loading the cart.
Partially supported or supported by alternative approach
- Adding new Checkout fields (commonly achieved with the
woocommerce_checkout_fieldshook)- Supported by the Additional Checkout Fields API, not all field types are supported right now
- Custom field validation using hooks such as woocommerce_checkout_process
- Supported by hooking into the payment processing events - validation at the point of pressing "Place order" this is only be possible for payment methods. Other extensions could add validation errors to the data store prior to the button being pressed, and this would prevent checkout, but it is not a good solution, especially if the validation checks are expensive.
- Updating orders/customers with hooks before/during/after order placement
- We have some hooks that fire during checkout:
woocommerce_store_api_checkout_order_processed- fired when the order has been placedwoocommerce_store_api_checkout_update_customer_from_request- fired when the customer is being updated with data from the checkout requestwoocommerce_store_api_checkout_update_order_meta- fired when order meta data is being updated with data from the request
- Any other WC hooks that fire in the Shortcode process (e.g.
woocommerce_checkout_order_processedwill not fire on Store API requests from the blocks)
- We have some hooks that fire during checkout:
- Customising the place order button text using
woocommerce_order_button_text- Not supported with hooks but it is possible in the editor. There is no programmatic way to achieve this right now.
Not supported at all
- Changing existing core fields (commonly achieved with the
woocommerce_checkout_fieldshook) - Removing billing/shipping addresses (using the above method)
- Performanign actions just before the order is finalised (
woocommerce_checkout_create_order)
Cart block
Fully supported with no modification needed
- None that aren't already covered by "both blocks" section.
Partially supported or supported by alternative approach
- Limiting quantity selections on cart items, e.g. minimum, maximum or step values. Previously this would be done using filters such as
woocommerce_quantity_input_step- This is possible by modifying the quantity_limits property of the cart item in the
woocommerce_store_api_product_quantity_{$value_type}filter.
- This is possible by modifying the quantity_limits property of the cart item in the
Not supported at all
- Modifying the layout by altering template files (unless using a block theme and a custom template)
Migrated legacy hooks
Below are the hooks that exist in WooCommerce core and that were brought over to WooCommerce Blocks.
Please note that the actions and filters here run on the server side. The client-side blocks won't necessarily change based on a callback added to a server side hook. Please see our documentation relating to APIs for manipulating the blocks on the client-side.
Legacy Filters
- loop_shop_per_page
- wc_session_expiration
- woocommerce_add_cart_item
- woocommerce_add_cart_item_data
- woocommerce_add_to_cart_quantity
- woocommerce_add_to_cart_sold_individually_quantity
- woocommerce_add_to_cart_validation
- woocommerce_adjust_non_base_location_prices
- woocommerce_apply_base_tax_for_local_pickup
- woocommerce_apply_individual_use_coupon
- woocommerce_apply_with_individual_use_coupon
- woocommerce_cart_contents_changed
- woocommerce_cart_item_permalink
- woocommerce_get_item_data
- woocommerce_loop_add_to_cart_args
- woocommerce_loop_add_to_cart_link
- woocommerce_new_customer_data
- woocommerce_pay_order_product_has_enough_stock
- woocommerce_pay_order_product_in_stock
- woocommerce_registration_errors
- woocommerce_shipping_package_name
- woocommerce_show_page_title
- woocommerce_single_product_image_thumbnail_html
Legacy Actions
- woocommerce_add_to_cart
- woocommerce_after_main_content
- woocommerce_after_shop_loop
- woocommerce_applied_coupon
- woocommerce_archive_description
- woocommerce_before_main_content
- woocommerce_before_shop_loop
- woocommerce_check_cart_items
- woocommerce_created_customer
- woocommerce_no_products_found
- woocommerce_register_post
- woocommerce_shop_loop
如何向 WooCommerce 结账阻止添加额外的字段
此功能需要 WooCommerce 8.9.0 或更高版本。
WooCommerce 结账阻止提供了一个强大的 API,供开发者在结账过程中从客户处收集额外的信息。 无论您需要收集特殊的送货说明、公司信息还是营销偏好,额外的结账字段都可以轻松扩展您的商店功能。
在本指南中,我们将逐步介绍如何向您的结账表单添加您自己的额外字段,并提供您可以立即实现的实用示例。
快速开始
要添加额外的结账字段,您将使用 woocommerce_register_additional_checkout_field() 函数。 应该在 woocommerce_init 操作之后调用此函数,以确保 WooCommerce 已完全加载。
以下是基本结构:
add_action( 'woocommerce_init', function() {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}
woocommerce_register_additional_checkout_field(
array(
'id' => 'your-namespace/field-name',
'label' => __( 'Your Field Label', 'your-text-domain'),
'location' => 'contact', // or 'address' or 'order'
'type' => 'text', // or 'select' or 'checkbox'
'required' => false,
)
);
});
字段位置:您的字段显示的位置
您可以将额外的字段放置在三个不同的位置:

联系方式 (contact)
这些字段显示在结账表单的顶部,位于电子邮件字段旁边。 保存在此处的数据将成为客户帐户的一部分,并在他们的“帐户详情”部分可见。
示例:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/marketing-opt-in',
'label' => __('Subscribe to our newsletter?', 'your-text-domain'),
'location' => 'contact',
'type' => 'checkbox',
)
);

地址 (address)
这些字段显示在收货地址和账单地址表单中。 它们同时保存到客户和订单,因此回头客无需再次填写。
示例:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/delivery-instructions',
'label' => __('Special delivery instructions', 'your-text-domain'),
'location' => 'address',
'type' => 'text',
)
);

订单信息 (order)
此位置的字段会显示在单独的“订单信息”块中,并且仅保存到订单,而不会保存到客户的帐户。非常适合用于特定于订单的详细信息,这些信息不需要在未来的购买中被记住。
示例:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/gift-message',
'label' => __('Gift message', 'your-text-domain'),
'location' => 'order',
'type' => 'text',
)
);

支持的字段类型
API 支持三种字段类型:
文本字段
非常适合收集简短的文本输入:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/company-vat',
'label' => __('VAT Number', 'your-text-domain'),
'location' => 'address',
'type' => 'text',
'required' => true,
)
);
下拉菜单
非常适合预定义的选项:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/preferred-delivery-time',
'label' => __('Preferred delivery time', 'your-text-domain'),
'location' => 'order',
'type' => 'select',
'options' => array(
array(
'value' => 'morning',
'label' => __('Morning (9AM - 12PM)', 'your-text-domain')
),
array(
'value' => 'afternoon',
'label' => __('Afternoon (12PM - 5PM)', 'your-text-domain')
),
array(
'value' => 'evening',
'label' => __('Evening (5PM - 8PM)', 'your-text-domain')
),
),
)
);
复选框
非常适合用于“是/否”问题或选择加入:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/age-verification',
'label' => __('I confirm I am over 18 years old', 'your-text-domain'),
'location' => 'contact',
'type' => 'checkbox',
'required' => true,
'error_message' => __('You must be over 18 to place this order.', 'your-text-domain'),
)
);
添加字段属性
您可以使用 HTML 属性来增强您的字段,以获得更好的用户体验: 示例:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/phone-number',
'label' => __('Alternative phone number', 'your-text-domain'),
'location' => 'contact',
'type' => 'text',
'attributes' => array(
'autocomplete' => 'tel',
'pattern' => '[0-9]{10}',
'title' => __('Please enter a 10-digit phone number', 'your-text-domain'),
'placeholder' => '1234567890',
),
)
);
验证和清理
为了确保您在自定义字段中输入的数据是有效且安全的,您可以添加自定义的验证和清理函数。
add_action( 'woocommerce_init', function() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/business-email',
'label' => __('Business Email', 'your-text-domain'),
'location' => 'contact',
'type' => 'text',
'required' => true,
'sanitize_callback' => function( $value ) {
return sanitize_email( $value );
},
'validate_callback' => function( $value ) {
if ( ! is_email( $value ) ) {
return new WP_Error(
'invalid_business_email',
__('Please enter a valid business email address.', 'your-text-domain')
);
}
},
)
);
});
验证
您还可以使用 WordPress 动作钩子进行验证:
add_action( 'woocommerce_validate_additional_field', function( $errors, $field_key, $field_value ) {
if ( 'my-plugin/business-email' === $field_key ) {
if ( ! is_email( $field_value ) ) {
$errors->add( 'invalid_business_email', __('Please enter a valid email address.', 'your-text-domain') );
}
}
}, 10, 3 );
访问字段值
结账后,您可以使用辅助方法检索字段值:
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
$checkout_fields = Package::container()->get( CheckoutFields::class );
$order = wc_get_order( $order_id );
// 获取特定字段值
$business_email = $checkout_fields->get_field_from_object(
'my-plugin/business-email',
$order,
'other' // 使用 'billing' 或 'shipping' 获取地址字段
);
// 获取所有附加字段
$all_fields = $checkout_fields->get_all_fields_from_object( $order, 'other' );
完整示例
add_action( 'woocommerce_init', function() {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}
// 公司信息
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-business-store/company-size',
'label' => __('公司规模', 'your-text-domain'),
'location' => '位置',
'type' => 'select',
'required' => true,
'options' => array(
array( 'value' => '1-10', 'label' => __('1-10名员工', 'your-text-domain') ),
array( 'value' => '11-50', 'label' => __('11-50名员工', 'your-text-domain') ),
array( 'value' => '51-200', 'label' => __('51-200名员工', 'your-text-domain') ),
array( 'value' => '200+', 'label' => __('200名以上员工', 'your-text-domain') ),
),
)
);
// 送货偏好
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-business-store/requires-appointment',
'label' => __('送货是否需要预约', 'your-text-domain'),
'location' => '地址',
'type' => '复选框',
)
);
// 订单相关的备注
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-business-store/po-number',
'label' => __('订单号', 'your-text-domain'),
'location' => '订单',
'type' => 'text',
)
);
});
下一步
现在,您已经为在您的 WooCommerce 商店中使用结账块添加额外的结账字段奠定了基础。
API 提供了强大的基础,用于自定义您的结账体验,同时保持与 WooCommerce 的基于块的结账系统的兼容性。 从简单的字段开始,并随着需求的增长,逐渐添加更复杂的验证和条件逻辑。
如何让您的 WooCommerce 附加结账字段在结账页面上根据条件显示
此功能需要 WooCommerce 9.9.0 或更高版本。
条件可见性允许您创建智能、自适应的结账表单,仅在需要时显示相关字段,从而减少表单的复杂性,并改善客户体验。
为什么使用条件可见性?
条件字段可以帮助您:
- 通过隐藏不相关的字段,减少表单的复杂性
- 根据客户的选择,创建动态的结账流程
- 仅为特定产品或客户类型显示专门的字段
- 通过更简洁、更集中的表单,提高转化率
- 收集仅在特定情况下才相关的上下文信息
了解用于条件的 JSON 结构化数据
WooCommerce 的附加结账字段使用 JSON 结构化数据来定义条件逻辑。 如果您不熟悉 JSON 结构化数据,请不要担心,我们将通过实际示例来演示,您可以根据自己的需求进行调整。
基本结构如下:
'required' => [
// 在此处定义隐藏条件
],
'hidden' => [
// 在此处定义隐藏条件
]
常见的条件场景
根据配送方式显示字段
最常见的用例之一是仅在选择特定配送方式时显示字段(例如,本地自提):
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/delivery-instructions',
'label' => __('特殊配送说明', 'your-text-domain'),
'location' => 'order',
'type' => 'text',
'required' => [
'cart' => [
'properties' => [
'prefers_collection' => [
'const' => true
]
]
]
],
'hidden' => [
'cart' => [
'properties' => [
'prefers_collection' => [
'const' => false
]
]
]
]
)
);
根据购物车内容显示字段
仅当购物车中包含特定产品时,显示字段:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/fragile-handling',
'label' => __('此订单包含易碎物品 - 需要特殊处理吗?', 'your-text-domain'),
'location' => 'order',
'type' => 'checkbox',
'required' => [
'cart' => [
'properties' => [
'items' => [
'contains' => [
'enum' => [2766, 456, 789] // 易碎物品的产品 ID
]
]
]
]
]
)
);
根据购物车数值显示字段
仅为高价值订单显示高级服务选项:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/white-glove-service',
'label' => __('Add white glove delivery service?', 'your-text-domain'),
'location' => 'order',
'type' => 'checkbox',
'hidden' => [
'cart' => [
'properties' => [
'totals' => [
'properties' => [
'totalPrice' => [
'maximum' => 50000 // 如果购物车总价 小于 $500 (以美分计),则隐藏
]
]
]
]
]
]
)
);
根据客户位置显示字段
仅为来自特定国家的客户显示字段:
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/tax-exemption-number',
'label' => __('Tax exemption number', 'your-text-domain'),
'location' => 'address',
'type' => 'text',
'required' => [
'customer' => [
'properties' => [
'address' => [
'properties' => [
'country' => [
'enum' => ['US', 'CA'] // 仅在美国和加拿大需要
]
]
]
]
]
],
'hidden' => [
'customer' => [
'properties' => [
'address' => [
'properties' => [
'country' => [
'not' => [
'enum' => ['US', 'CA'] // 对于美国和加拿大以外的国家隐藏
]
]
]
]
]
]
]
)
);
根据其他字段值显示字段
创建依赖字段,其中一个字段的可见性取决于另一个字段的值:
// 第一个字段 - 服务类型选择
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/service-type',
'label' => __('Type of service needed', 'your-text-domain'),
'location' => 'order',
'type' => 'select',
'options' => array(
array( 'value' => 'standard', 'label' => 'Standard' ),
array( 'value' => 'express', 'label' => 'Express' ),
array( 'value' => 'custom', 'label' => 'Custom' ),
),
)
);
// 第二个字段 - 仅当选择 "custom" 时显示
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-plugin/custom-requirements',
'label' => __('Describe your custom requirements', 'your-text-domain'),
'location' => 'order',
'type' => 'text',
'required' => [
'checkout' => [
'properties' => [
'additional_fields' => [
'properties' => [
'my-plugin/service-type' => [
'const' => 'custom'
]
]
]
]
]
],
'hidden' => [
'checkout' => [
'properties' => [
'additional_fields' => [
'properties' => [
'my-plugin/service-type' => [
'not' => [
'const' => 'custom'
]
]
]
]
]
]
]
)
);
实用完整示例
这是一个针对提供数字和实体产品的商店的综合示例:
add_action( 'woocommerce_init', function() {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}
// 配送偏好 - 仅适用于实体产品
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-store/delivery-preference',
'label' => __('配送偏好', 'your-text-domain'),
'location' => 'order',
'type' => 'select',
'options' => array(
array( 'value' => 'doorstep', 'label' => __('放置在门前', 'your-text-domain') ),
array( 'value' => 'neighbor', 'label' => __('交给邻居', 'your-text-domain') ),
array( 'value' => 'pickup_point', 'label' => __('送至取件点', 'your-text-domain') ),
),
'required' => [
'cart' => [
'properties' => [
'needs_shipping' => [
'const' => true
]
]
]
],
'hidden' => [
'cart' => [
'properties' => [
'needs_shipping' => [
'const' => false
]
]
]
]
)
);
// 配送说明 - 仅当选择“放置在门前”时显示
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-store/doorstep-instructions',
'label' => __('关于门前配送的详细说明', 'your-text-domain'),
'location' => 'order',
'type' => 'text',
'required' => [
'checkout' => [
'properties' => [
'additional_fields' => [
'properties' => [
'my-store/delivery-preference' => [
'const' => 'doorstep'
]
]
]
]
]
],
'hidden' => [
'checkout' => [
'properties' => [
'additional_fields' => [
'properties' => [
'my-store/delivery-preference' => [
'not' => [
'const' => 'doorstep'
]
]
]
]
]
]
]
)
);
// 数字产品配送邮箱 - 仅适用于数字产品
woocommerce_register_additional_checkout_field(
array(
'id' => 'my-store/digital-delivery-email',
'label' => __('用于数字产品的备用邮箱', 'your-text-domain'),
'location' => 'contact',
'type' => 'text',
'required' => [
'cart' => [
'properties' => [
'needs_shipping' => [
'const' => false
]
]
]
],
'hidden' => [
'cart' => [
'properties' => [
'needs_shipping' => [
'const' => true
]
]
]
],
'sanitize_callback' => function ( $field_value ) {
return sanitize_email( $field_value );
},
'validate_callback' => function ( $field_value ) {
if ( ! is_email( $field_value ) ) {
return new \WP_Error( 'invalid_alt_email', __('请确保您的备用邮箱符合正确的格式。', 'your-text-domain') );
}
},
)
);
});
可用于条件的可用数据
您可以基于各种结账数据创建条件:
- 购物车信息:总价、商品数量、配送费率、优惠券、重量
- 客户数据:ID、账单/配送地址、电子邮件
- 其他附加字段:来自其他自定义字段的参考值以及更多!
下一步
条件可见性将静态结账表单转换为动态、智能的界面,这些界面可以根据客户的需求进行调整。 结合我们上一篇文章中介绍的基本附加字段,您可以创建复杂的结账体验,以便在正确的时间收集到准确的信息。
从简单的条件开始,逐步构建更复杂的逻辑,随着您对 JSON 结构化数据语法越来越熟悉。 您的客户将欣赏更简洁、更相关的结账体验!
与结账模块集成保护功能
如果您是 CAPTCHA 或欺诈防护插件的开发者,请确保您的解决方案与 Store API 接口对接,并与结账模块进行集成。本教程将指导您完成向 WooCommerce 结账模块添加保护机制的流程。
概述
WooCommerce 结账模块使用 Store API 来处理订单,它提供一个安全、未认证的 API,用于面向客户的功能。为了集成保护机制,例如 CAPTCHA 或欺诈检测,您需要:
- 渲染您的保护元素,使用 WordPress 块过滤器将其插入到结账模块中。
- 处理客户端验证,使用结账数据存储。
- 在服务器端进行验证,使用 Store API 的认证钩子。
第一步:渲染您的保护元素
第一步是渲染您的 CAPTCHA 或保护元素到结账模块中。您可以使用 render_block 过滤器,在特定的结账模块之前或之后注入您的 HTML。
使用 render_block 过滤器
render_block 过滤器允许您修改任何 WordPress 块的输出。对于结账模块,您需要针对 woocommerce/checkout-actions-block,该模块包含“提交订单”按钮。
add_filter(
'render_block_woocommerce/checkout-actions-block',
function( $block_content ) {
ob_start();
?>
<div class="my-captcha-element" data-sitekey="<?php echo esc_attr( get_option( 'plugin_captcha_sitekey' ) ); ?>">
</div>
<?php
echo $block_content;
$block_content = ob_get_contents();
ob_end_clean();
return $block_content;
},
999,
1
);
此代码的关键点:
- 该过滤器针对
woocommerce/checkout-actions-block,即包含提交订单按钮的块。 - 我们使用优先级
999,以确保我们的内容在其他修改之后添加。 data-sitekey属性存储您的 CAPTCHA 配置,但对于您的插件,这可能会有所不同。- 我们将在原始块内容之后附加我们的保护元素。
第二步:客户端集成
一旦您的保护元素被渲染,您需要将其与结账数据存储集成,以捕获验证令牌,并将其传递到服务器。
使用结账数据存储
结账模块使用数据存储来管理状态。 您可以使用 setExtensionData 方法将您的保护令牌传递给服务器。
/* Woo 结账模块 */
document.addEventListener( 'DOMContentLoaded', function () {
if ( wp && wp.data ) {
var unsubscribe = wp.data.subscribe( function () {
const turnstileItem = document.querySelector(
'.my-captcha-element'
);
if ( turnstile && turnstileItem ) {
turnstile.render( turnstileItem, {
sitekey: turnstileItem.dataset.sitekey,
callback: function ( data ) {
wp.data
.dispatch( 'wc/store/checkout' )
.setExtensionData( 'plugin-namespace-turnstile', {
token: data,
} );
},
} );
unsubscribe();
}
}, 'wc/store/cart' );
}
} );
关于此 JavaScript 的关键点:
- 我们订阅购物车数据存储,以便检测结账是否已准备就绪。
turnstile.render()方法初始化您的验证码(替换为您的特定实现)。setExtensionData()将令牌存储在结账数据存储中。- 命名空间应是您插件的唯一标识(例如,
my-plugin-turnstile)。
数据存储集成
有关结账数据存储和可用方法的更多信息,请参阅 结账数据存储文档。
第 3 步:服务器端验证
最关键的步骤是在服务器端验证保护令牌。 这应该在身份验证过程的早期发生,以防止任何未经授权的结账尝试。
使用核心 rest_authentication_errors 过滤器
[rest_authentication_errors](https://developer.wordpress.org/reference/hooks/rest_authentication_errors/) 过滤器是验证您的保护令牌的理想位置,因为它在任何结账处理开始之前运行。
add_filter( 'rest_authentication_errors', 'plugin_check_turnstile_token' );
function plugin_check_turnstile_token( $result ) {
// 如果不是 POST 请求,则跳过。
if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] !== 'POST' ) {
// 始终返回结果或错误,切勿返回布尔值。 这可确保其他检查(例如速率限制或身份验证)不会被忽略。
return $result;
}
// 如果不是结账端点,则跳过。
if ( ! preg_match( '#/wc/store(?:/v\d+)?/checkout#', $GLOBALS['wp']->query_vars['rest_route'] ) ) {
return $result;
}
// 获取请求体
$request_body = json_decode( \WP_REST_Server::get_raw_data(), true );
if ( isset( $request_body['payment_method'] ) ) {
$chosen_payment_method = sanitize_text_field( $request_body['payment_method'] );
// 提供一种机制,允许跳过检查,以便允许快速付款或托管结账绕过检查。
$selected_payment_methods = apply_filters( 'plugin_payment_methods_to_skip', array('woocommerce_payments' ) );
if( is_array( $selected_payment_methods ) ) {
if ( in_array( $chosen_payment_method, $selected_payment_methods, true ) ) {
return $result;
}
}
}
$extensions = $request_body['extensions'];
if ( empty( $extensions ) || ! isset( $extensions['plugin-namespace-turnstile'] ) ) {
return new WP_Error( 'challenge_failed', '验证码挑战失败' );
}
$token = sanitize_text_field( $extensions['plugin-namespace-turnstile']['token'] );
/**
* 注意:函数 `my_token_check_function` 将在您的插件中实现,以处理令牌验证。
**/
$check = my_token_check_function( $token );
$success = $check['success'];
if( $success !== true ) {
return new WP_Error( 'challenge_failed', '验证码挑战失败' );
}
return $result;
}
关于服务器端验证的关键点:
- 我们专门检查发送到结账端点的 POST 请求。
- 保护令牌通过
$request_body['extensions']['your-namespace']访问。 - 始终返回
$result参数,以避免干扰其他身份验证检查。 - 如果验证失败,则返回一个
WP_Error对象。 - 考虑允许某些付款方式绕过保护(例如,快速付款)。
重要提示
安全注意事项
- 始终在服务器端进行验证 - 客户端验证可以被绕过。
- 使用 HTTPS - 保护令牌应通过安全的方式传输。
- 速率限制 - 考虑为您的保护端点实施 速率限制。
- 令牌过期 - 确保您的保护令牌具有适当的过期时间。
测试您的集成
在测试您的保护集成时:
- 启用结账阻止进行测试。
- 验证当未提供令牌时,验证失败。
- 使用不同的付款方式进行测试。
- 确保保护功能不会干扰合法的结账流程。
添加一个国家
使用以下代码片段,将国家添加到您的国家列表:
if ( ! function_exists( 'YOUR_PREFIX_add_country_to_countries_list' ) ) {
/**
* 将国家添加到国家列表
*
* @param array $countries 存在的国家列表。
* @return array $countries 修改后的国家列表。
*/
function YOUR_PREFIX_add_country_to_countries_list( $countries ) {
$new_countries = array(
'NIRE' => __( 'Northern Ireland', 'YOUR-TEXTDOMAIN' ),
);
return array_merge( $countries, $new_countries );
}
add_filter( 'woocommerce_countries', 'YOUR_PREFIX_add_country_to_countries_list' );
}
if ( ! function_exists( 'YOUR_PREFIX_add_country_to_continents_list' ) ) {
/**
* 将国家添加到大陆列表
*
* @param array $continents 存在的地区列表。
* @return array $continents 修改后的地区列表。
*/
function YOUR_PREFIX_add_country_to_continents_list( $continents ) {
$continents['EU']['countries'][] = 'NIRE';
return $continents;
}
add_filter( 'woocommerce_continents', 'YOUR_PREFIX_add_country_to_continents_list' );
}
添加货币和符号
将自定义货币添加到您的货币列表中:
if ( ! function_exists( 'YOUR_PREFIX_add_currency_name' ) ) {
/**
* 添加自定义货币
*
* @param array $currencies 现有的货币。
* @return array $currencies 已更新的货币。
*/
function YOUR_PREFIX_add_currency_name( $currencies ) {
$currencies['ABC'] = __( '货币名称', 'YOUR-TEXTDOMAIN' );
return $currencies;
}
add_filter( 'woocommerce_currencies', 'YOUR_PREFIX_add_currency_name' );
}
if ( ! function_exists( 'YOUR_PREFIX_add_currency_symbol' ) ) {
/**
* 添加自定义货币符号
*
* @param string $currency_symbol 现有的货币符号。
* @param string $currency 货币代码。
* @return string $currency_symbol 已更新的货币符号。
*/
function YOUR_PREFIX_add_currency_symbol( $currency_symbol, $currency ) {
switch( $currency ) {
case 'ABC': $currency_symbol = '$'; break;
}
return $currency_symbol;
}
add_filter('woocommerce_currency_symbol', 'YOUR_PREFIX_add_currency_symbol', 10, 2);
}
添加或修改州/省
在 WooCommerce 中,您可以添加自己的州/省信息或修改现有的州/省信息。
注意:您必须将 XX 的两个实例都替换为您的国家/地区代码。这意味着数组中的每个州/省 ID 必须在您分配给该州/省的数值前面加上您的两个字母的国家/地区代码。
if ( ! function_exists( 'YOUR_PREFIX_add_or_modify_states' ) ) {
/**
* 添加或修改州/省
*
* @param array $states 现有的国家/地区州/省信息。
* @return array $states 修改后的国家/地区州/省信息。
*/
function YOUR_PREFIX_add_or_modify_states( $states ) {
$states['XX'] = array(
'XX1' => __( 'State 1', 'YOUR-TEXTDOMAIN' ),
'XX2' => __( 'State 2', 'YOUR-TEXTDOMAIN' ),
);
return $states;
}
add_filter( 'woocommerce_states', 'YOUR_PREFIX_add_or_modify_states' );
}
调整数量输入框的值
设置产品网页上数量输入框的起始值、最大值、最小值和递增量。
if ( ! function_exists( 'YOUR_PREFIX_woocommerce_quantity_input_args' ) ) {
/**
* 调整简单产品的数量输入框的值
*/
function YOUR_PREFIX_woocommerce_quantity_input_args( $args, $product ) {
// 仅影响产品网页上的起始值,不影响购物车
if ( is_singular( 'product' ) ) {
$args['input_value'] = 4;
}
$args['max_value'] = 10; // 最大值
$args['min_value'] = 2; // 最小值
$args['step'] = 2; // 数量 递增
return $args;
}
add_filter( 'woocommerce_quantity_input_args', 'YOUR_PREFIX_woocommerce_quantity_input_args', 10, 2 );
}
if ( ! function_exists( 'YOUR_PREFIX_woocommerce_available_variation' ) ) {
/**
* 调整变体的数量输入框的值
*/
function YOUR_PREFIX_woocommerce_available_variation( $args ) {
$args['max_qty'] = 20; // 最大值 (变体)
$args['min_qty'] = 2; // 最小值 (变体)
// 注意:变体的起始值和 步骤 由上面的 'woocommerce_quantity_input_args' 过滤器控制,
// 用于 简单产品
return $args;
}
add_filter( 'woocommerce_available_variation', 'YOUR_PREFIX_woocommerce_available_variation' );
}
如果您需要更多功能,请查看我们的 Min/Max Quantities 扩展程序!
在登录/注册表单上方添加一条信息
这段代码将在用户的“我的账户”页面,在登录/注册表单上方添加自定义信息。
if ( ! function_exists( 'YOUR_PREFIX_login_message' ) ) {
/**
* 在“我的账户”页面,在登录/注册表单上方添加一条信息
*/
function YOUR_PREFIX_login_message() {
if ( get_option( 'woocommerce_enable_myaccount_registration' ) == 'yes' ) {
?>
<div class="woocommerce-info">
<p><?php _e( 'Returning customers login. New users register for next time so you can:', 'YOUR-TEXTDOMAIN' ); ?></p>
<ul>
<li><?php _e( 'View your order history', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Check on your orders', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Edit your addresses', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Change your password', 'YOUR-TEXTDOMAIN' ); ?></li>
</ul>
</div>
<?php
}
}
add_action( 'woocommerce_before_customer_login_form', 'YOUR_PREFIX_login_message' );
}
请注意,要使此代码正常工作,必须在 WooCommerce 的“账户与隐私”设置中选中以下选项:
- 允许客户在结账时创建账户。
- 允许客户在“我的账户”页面创建账户。
更改货币符号
在 WooCommerce 中,每种货币都与一个代码和一个符号相关联。例如,澳大利亚元的代码是 AUD,符号是 $(如果您感兴趣,您可以在 源代码 中查看完整的代码和符号列表)。
但是,可能存在您希望更改符号的情况。以澳大利亚元的例子为例,它使用的符号与许多其他美元货币相同,因此,在某些可能导致混淆的情况下,将其更改为 AUD$ 可能会很有用。以下代码片段概述了如何执行此操作:
if ( ! function_exists( 'YOUR_PREFIX_change_currency_symbol' ) ) {
/**
* 更改货币符号
*
* @param string $currency_symbol 现有的货币符号。
* @param string $currency 货币代码。
* @return string $currency_symbol 更新后的货币符号。
*/
function YOUR_PREFIX_change_currency_symbol( $currency_symbol, $currency ) {
switch ( $currency ) {
case 'AUD': $currency_symbol = 'AUD$'; break;
}
return $currency_symbol;
}
add_filter( 'woocommerce_currency_symbol', 'YOUR_PREFIX_change_currency_symbol', 10, 2 );
}
您可以在 switch 语句中添加其他 case 语句,以对您支持的任何其他货币执行类似的更改。
检查付款方式是否支持退款、订阅或预购
如果某个付款方式的文档没有明确说明其支持的功能,您通常可以通过查看付款方式的代码来了解其支持哪些功能。
付款方式可以添加对 WooCommerce 及其扩展程序中某些功能的支持。例如,一个付款方式可以支持退款、订阅或预购功能。
Simplify Commerce 示例
以 Simplify Commerce 付款方式为例,在您喜欢的编辑器中打开插件文件,并搜索 $this->supports。您将找到支持的功能:
class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway {
/** * Constructor */
public function __construct() {
$this->id
= 'simplify_commerce';
$this->method_title
= __( 'Simplify Commerce', 'woocommerce' );
$this->method_description = __( 'Take payments via Simplify Commerce - uses simplify.js to create card tokens and the Simplify Commerce SDK. Requires SSL when sandbox is disabled.', 'woocommerce' );
$this->has_fields = true;
$this->supports = array(
'subscriptions',
'products',
'subscription_cancellation',
'subscription_reactivation',
'subscription_suspension',
'subscription_amount_changes',
'subscription_payment_method_change',
'subscription_date_changes',
'default_credit_card_form',
'refunds',
'pre-orders'
);
如果您在插件文件中找不到 $this->supports,这可能意味着该付款方式没有正确声明对退款、下标或预购的支持。
配置特殊税收场景的代码示例
场景 A:无论位置和税收,都收取相同的价格
如果商店在输入产品价格时已经包含了税费,但同时应用了各种基于位置的税率,那么价格可能会因为不同的税率而显示不同。实际上,基础价格保持不变,税费影响的是总价。 请点击此链接以获取详细说明。
一些商家希望动态调整产品的基础价格,以弥补税费的变化,从而保持总价的一致性,无论税率如何。可以通过将以下代码片段添加到子主题的 functions.php 文件或通过代码片段插件来启用此功能。
<?php
add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
场景 B:根据小计金额收取税费
以下代码片段适用于商店仅在小计达到指定最小值时才收取税费的情况。在下面的代码片段中,该最小值是商店货币的 110。请根据您的需求调整代码片段。
<?php
add_filter( 'woocommerce_product_get_tax_class', 'big_apple_get_tax_class', 1, 2 );
function big_apple_get_tax_class( $tax_class, $product ) {
if ( WC()->cart->subtotal <= 110 )
$tax_class = 'Zero Rate';
return $tax_class;
}
场景 C:根据用户角色应用不同的税率
某些商家可能需要根据用户角色应用不同的税率,以适应批发状态或税收免除的情况。
要启用此功能,请将以下代码片段添加到子主题的 functions.php 文件或通过代码片段插件。在此代码片段中,具有 "administrator" 权限的用户将被分配 零税率税类。请根据您的需求进行调整。
<?php
/**
* 根据用户角色应用不同的税率。
*/
function wc_diff_rate_for_user( $tax_class, $product ) {
if ( is_user_logged_in() && current_user_can( 'administrator' ) ) {
$tax_class = 'Zero Rate';
}
return $tax_class;
}
add_filter( 'woocommerce_product_get_tax_class', 'wc_diff_rate_for_user', 1, 2 );
add_filter( 'woocommerce_product_variation_get_tax_class', 'wc_diff_rate_for_user', 1, 2 );
场景 D:显示 0 值税费
默认情况下,具有 0 值的税费会被隐藏。要始终显示它们,请将以下代码片段添加到主题的 functions.php 文件或通过代码片段插件:
add_filter( 'woocommerce_order_hide_zero_taxes', '__return_false' );
场景 E:在主可变产品上使用后缀
WooCommerce 的一个税务设置允许使用后缀,以便为产品价格添加其他信息。 它可以用于可变产品的变体,但默认情况下在主变体级别禁用,因为当存在大量变体时,这可能会影响网站性能。
负责相关价格输出的方法,如果需要,可以通过过滤器钩子进行自定义,尤其是在处理可变产品时。 这需要进行自定义,可以通过以下过滤器来实现:
add_filter( 'woocommerce_show_variation_price', '__return_true' );
使用操作和过滤器自定义结账字段
如果您不熟悉代码以及解决潜在的冲突,我们有一个扩展程序可以提供帮助:WooCommerce 结账字段编辑器。安装并激活此扩展程序会覆盖您尝试实现的任何代码;当扩展程序激活时,您不能在 functions.php 文件中包含自定义结账字段的代码。
自定义代码应复制到子主题的 functions.php 文件中。
注意
文档的某些部分仅适用于短代码 Checkout,要向 Checkout 块添加字段,请参阅 额外的结账字段文档。
WooCommerce 如何加载结账字段?
结账过程中的账单和配送字段,来源于 class-wc-countries.php 类以及 get_address_fields 函数。 这使得 WooCommerce 可以根据用户的 位置 启用/禁用字段。
在返回这些字段之前,WooCommerce 会将这些字段经过一个 过滤器。 这允许第三方插件、主题以及您的 自定义代码 对其进行编辑。
账单:
$address_fields = apply_filters( 'woocommerce_billing_fields', $address_fields );
配送:
$address_fields = apply_filters( 'woocommerce_shipping_fields', $address_fields );
结账类将加载的字段添加到其 checkout_fields 数组中,并添加一些其他字段,例如 "订单备注"。
$this->checkout_fields['billing'] = $woocommerce->countries->get_address_fields( $this->get_value( 'billing_country' ), 'billing_' );
$this->checkout_fields['shipping'] = $woocommerce->countries->get_address_fields( $this->get_value( 'shipping_country' ), 'shipping_' );
$this->checkout_fields['account'] = array(
'account_username' => array(
'type' => 'text',
'label' => __( 'Account username', 'woocommerce' ),
'placeholder' => _x( 'Username', 'placeholder', 'woocommerce' ),
),
'account_password' => array(
'type' => 'password',
'label' => __( 'Account password', 'woocommerce' ),
'placeholder' => _x( 'Password', 'placeholder', 'woocommerce' ),
'class' => array( 'form-row-first' )
),
'account_password-2' => array(
'type' => 'password',
'label' => __( 'Account password', 'woocommerce' ),
'placeholder' => _x( 'Password', 'placeholder', 'woocommerce' ),
'class' => array( 'form-row-last' ),
'label_class' => array( 'hidden' )
),
);
$this->checkout_fields['order'] = array(
'order_comments' => array(
'type' => 'textarea',
'class' => array( 'notes' ),
'label' => __( 'Order Notes', 'woocommerce' ),
'placeholder' => _x( 'Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce' )
)
);
这个数组也会经过一个过滤器:
$this->checkout_fields = apply_filters( 'woocommerce_checkout_fields', $this->checkout_fields );
这意味着您对结账字段拥有 完全的控制权 - 您只需要知道如何 访问 它们。
覆盖核心字段
通过使用 woocommerce_checkout_fields 过滤器,您可以覆盖任何字段。 例如,让我们更改 order_comments 字段的占位符。 目前,它设置为:
_x( 'Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce' );
我们可以通过将一个函数添加到我们的主题 functions.php 文件中来更改它:
// 注册钩子
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// 注册的函数 - $fields 通过过滤器传递!
function custom_override_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = 'My new placeholder';
return $fields;
}
您可以覆盖其他部分,例如标签:
// 注册钩子
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// 注册的函数 - $fields 通过过滤器传递!
function custom_override_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = 'My new placeholder';
$fields['order']['order_comments']['label'] = 'My new label';
return $fields;
}
或者移除字段:
// 注册钩子
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// 注册的函数 - $fields 通过过滤器传递!
function custom_override_checkout_fields( $fields ) {
unset( $fields['order']['order_comments'] );
return $fields;
}
以下是传递给 woocommerce_checkout_fields 的数组中的所有字段列表:
- Billing (账单)
billing_first_namebilling_last_namebilling_companybilling_address_1billing_address_2billing_citybilling_postcodebilling_countrybilling_statebilling_emailbilling_phone
- Shipping (配送)
shipping_first_nameshipping_last_nameshipping_companyshipping_address_1shipping_address_2shipping_cityshipping_postcodeshipping_countryshipping_state
- Account (账户)
account_usernameaccount_passwordaccount_password-2
- Order (订单)
order_comments
每个字段都包含一个数组,其中包含以下属性:
type- 字段类型 (text, textarea, password, select)label- 输入字段的标签placeholder- 输入的占位符class- 输入的类required- true 或 false,表示该字段是否是必填项clear- true 或 false,应用于字段/标签的清除样式label_class- 标签元素的类options- 对于下拉框,选项数组 (键 => 值 对)
在特定情况下,您需要使用 woocommerce_default_address_fields 过滤器。 此过滤器应用于所有账单和配送默认字段。
自定义 WooCommerce 默认地址字段
本指南将介绍如何自定义 WooCommerce 默认的地址字段。
字段:
countryfirst_namelast_namecompanyaddress_1address_2citystatepostcode
例如,要将 address_1 字段设置为可选:
// 钩子
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
// 我们的钩子函数 - `$address_fields` 通过**过滤器**传递!
function custom_override_default_address_fields( $address_fields ) {
$address_fields['address_1']['required'] = false;
return $address_fields;
}
说明:
add_filter()函数用于添加一个钩子,该钩子允许我们修改 WooCommerce 的默认行为。woocommerce_default_address_fields是一个过滤器,它允许我们修改默认的地址字段。custom_override_default_address_fields是一个自定义函数,用于修改地址字段。$address_fields是一个数组,包含所有地址字段的信息。required属性用于指定一个字段是否为必填。false值表示该字段为可选。return $address_fields;语句将修改后的地址字段数组返回。
通过使用上述代码,您可以轻松地自定义 WooCommerce 的地址字段,以满足您的特定需求。 您可以修改任何字段的属性,例如使其成为必填或可选,或者添加自定义属性。 请记住,在修改任何代码之前,请务必备份您的网站。
定义选择选项
如果您正在添加一个类型为 'select' 的字段,如上所述,您需要定义键/值对。例如:
$fields['billing']['your_field']['options'] = array(
'option_1' => 'Option 1 text',
'option_2' => 'Option 2 text'
);
优先级
在 PHP 代码中,优先级用于确定一段代码(称为函数)在网页加载过程中执行的时机。它在每个函数内部设置,并且在覆盖现有代码以进行自定义显示时非常有用。
具有较高数值的优先级代码将在具有较低数值的优先级代码之后运行,这意味着优先级为 20 的代码将在优先级为 10 的代码之后运行。
优先级参数是在 add_action 函数中设置的,在您确定要连接的钩子以及自定义函数的名称之后。
在下面的示例中,蓝色文本是我们要修改的钩子的名称,绿色文本是我们的自定义函数的名称,红色是设置的优先级。

示例
修改“返回商店”按钮的重定向 URL
在这个示例中,代码被设置为将购物车中找到的“返回商店”按钮重定向到 http://example.url/category/specials/ 所在的分类页面。
/**
* 更改购物车中“返回商店”按钮的重定向 URL。
*/
function wc_empty_cart_redirect_url() {
return 'http://example.url/category/specials/';
}
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 10 );
在那里,我们可以看到优先级被设置为 10。 这是 WooCommerce 函数和脚本的典型默认值,因此可能不足以覆盖该按钮的功能。
相反,我们可以将优先级更改为大于 10 的任何数字。 虽然 11 可以工作,但最佳实践建议我们使用 10 的倍数,例如 20、30 等。
/**
* 更改购物车中“返回商店”按钮的重定向 URL。
*/
function wc_empty_cart_redirect_url() {
return 'http://example.com/category/specials/';
}
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 20 );
通过优先级,我们可以拥有两个函数作用于同一个钩子。 通常,这会导致各种问题,但由于我们已经确定一个函数的优先级高于另一个函数,因此我们的站点只会加载适当的函数,并且我们将按照以下代码的预期被重定向到“特价”页面。
/**
* 更改购物车中“返回商店”按钮的重定向 URL。
* 因为这个函数具有 20 的优先级,所以它将在下面的函数之后运行(更高的数字运行在后面)。
*/
function wc_empty_cart_redirect_url() {
return 'http://example.com/category/specials/';
}
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 20 );
/**
* 更改购物车中“返回商店”按钮的重定向 URL。
* 即使这个函数通常会在后面运行,因为它的代码在后面,但其 10 的优先级低于上面的 20。
*/
function wc_empty_cart_redirect_url() {
return 'http://example.com/shop/';
}
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 10 );
添加自定义的配送和账单字段
添加字段的方式与覆盖字段类似。例如,让我们添加一个新的字段到配送字段中 - shipping_phone:
// 钩子
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// 我们的钩子函数 - $fields 通过过滤器传递!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __( '电话', 'woocommerce' ),
'placeholder' => _x( '电话', '占位符', 'woocommerce' ),
'required' => false,
'class' => array( 'form-row-wide' ),
'clear' => true
);
return $fields;
}
/**
* 在订单编辑页面显示字段值
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong >'. esc_html__( '来自结账表单的电话' ) . ':</strong > ' . esc_html( $order->get_meta( '_shipping_phone', true ) ) . '</p>';
}

它已经生效!
我们用这个新字段做什么? 没什么。 因为我们在 checkout_fields 数组中定义了该字段,所以该字段会自动处理并保存到订单的元数据中(在本例中,为 _shipping_phone)。 如果您想添加验证规则,请参阅结账类,其中有其他您可以使用的钩子。
添加自定义特殊字段
添加自定义字段的方法类似。 让我们在订单备注之后,向结账页面添加一个新的字段,通过以下钩子实现:
/**
* 将字段添加到结账页面
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . esc_html__( 'My Field' ) . '</h2>';
woocommerce_form_field(
'my_field_name',
array(
'type' => 'text',
'class' => array( 'my-field-class form-row-wide' ),
'label' => __( 'Fill in this field' ),
'placeholder' => __( 'Enter something' ),
),
$checkout->get_value( 'my_field_name' )
);
echo '</div>';
}
这样会得到:

接下来,我们需要在提交结账表单时验证该字段。 在这个例子中,我们检查该字段是否只包含字母:
/**
* 处理结账
*/
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process' );
function my_custom_checkout_field_process() {
// 检查该字段是否只包含字母。
if ( ! preg_match( '/^[a-zA-Z]+$/', $_POST['my_field_name'] ) ) {
wc_add_notice( esc_html__( '请仅在新的漂亮字段中输入字母。' ), 'error' );
}
}
如果该字段为空,则会显示一个结账错误:

最后,使用以下代码将新的字段保存到订单自定义字段:
/**
* 使用字段值更新订单元数据
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
$order = wc_get_order( $order_id );
$order->update_meta_data( 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
$order->save_meta_data();
}
}
该字段现在已保存到订单。
如果您希望在管理员订单编辑页面上显示自定义字段的值,您可以添加以下代码:
/**
* 在订单编辑页面上显示字段值
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ){
echo '<p><strong>' . esc_html__( 'My Field' ) . ':</strong> ' . esc_html( $order->get_meta( 'My Field', true ) ) . '</p>';
}
结果如下:

使电话号码非必填
add_filter( 'woocommerce_billing_fields', 'wc_npr_filter_phone', 10, 1 );
function wc_npr_filter_phone( $address_fields ) {
$address_fields['billing_phone']['required'] = false;
return $address_fields;
}
以编程方式禁用市场场所建议功能
对于那些希望通过编程方式禁用从 woocommerce.com 获取的市场场所建议功能的用户,请将 woocommerce_allow_marketplace_suggestions 过滤器添加到您的主题的 functions.php 文件或自定义插件中。
例如:
add_filter( 'woocommerce_allow_marketplace_suggestions', '__return_false' );
此过滤器将完全从您的 WooCommerce 管理员界面移除市场场所建议功能。
在您的主题或网站中显示自定义字段
您可以利用添加到产品的自定义字段中的元数据,以便在您的主题或网站中显示这些附加的信息。
要为每个产品显示自定义字段,您需要编辑您主题的文件。以下是一个示例,说明如何在单个产品页面上,在简短描述之后显示一个自定义字段:

<?php
// 在单个产品页面上,在简短描述之后显示一个产品自定义字段
function woocommerce_custom_field_example() {
if ( ! is_product() ) {
return;
}
global $product;
if ( ! is_object( $product ) ) {
$product = wc_get_product( get_the_ID() );
}
$custom_field_value = get_post_meta( $product->get_id(), 'woo_custom_field', true );
if ( ! empty( $custom_field_value ) ) {
echo '<div class="custom-field">' . esc_html( $custom_field_value ) . '</div>';
}
}
add_action( 'woocommerce_before_add_to_cart_form', 'woocommerce_custom_field_example', 10 );
免费配送自定义设置
免费配送:高级设置/自定义
概述
默认情况下,WooCommerce 会显示所有与客户和购物车内容匹配的配送方式。这意味着免费配送也会与统一费率和其他配送方式一起显示。
要隐藏所有其他配送方式,只显示免费配送,需要使用自定义 PHP 代码或插件/扩展。
添加代码
在添加代码片段之前,请清除您的 WooCommerce 缓存。转到 WooCommerce > 系统状态 > 工具 > WooCommerce 瞬态 > 清除瞬态。
代码片段
如何只显示免费配送?
以下代码片段将在免费配送可用时隐藏所有其他配送方式。
/**
* 当免费配送可用时,隐藏其他配送费率。
*
* @param array $rates 找到的费率数组。
*
* @return array
*/
function fsc_hide_shipping_rates_when_free_is_available( $rates ) {
// 遍历找到的每个费率。
foreach ( $rates as $rate_id => $rate ) {
// 如果找到免费配送,将其定义为唯一的费率,并退出 foreach 循环。
if ( 'free_shipping' === $rate->method_id ) {
$rates = [ $rate_id => $rate ];
break;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'fsc_hide_shipping_rates_when_free_is_available', 10, 1 );
如何只显示本地自提和免费配送?
以下代码片段将在免费配送可用时隐藏所有其他配送方式,但如果本地自提可用,则会显示本地自提。
/**
* 如果免费配送可用,则隐藏其他费率,排除本地自提。
*
* @param array $rates 找到的费率数组。
*
* @return array
*/
function fsc_hide_shipping_rates_when_free_is_available_excluding_local( $rates ) {
// 定义数组,用于存储免费配送和本地自提方法,如果找到。
$free_shipping = [];
$local_pickup = [];
// 遍历接收到的每个费率。
foreach ( $rates as $rate_id => $rate ) {
// 如果找到任何一种方法,将其添加到其各自的数组中。
if ( 'free_shipping' === $rate->method_id ) {
$free_shipping[ $rate_id ] = $rate;
continue;
}
if ( 'pickup_location' === $rate->method_id ) {
$local_pickup[ $rate_id ] = $rate;
}
}
// 如果 free_shipping 数组包含一种方法,则将 local_pickup 合并到其中,并覆盖 rates 数组。
if ( ! empty( $free_shipping ) ) {
$rates = array_merge( $free_shipping, $local_pickup );
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'fsc_hide_shipping_rates_when_free_is_available_excluding_local', 10, 1 );
通过钩子启用或禁用免费配送
如果您想通过编程方式了解是否可用免费配送,这是可能的。WooCommerce 提供了类似于以下的代码过滤器:
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available );
这意味着您可以使用 add_filter() 函数,目标是 woocommerce_shipping_free_shipping_is_available,并接收 true 或 false,以确定是否已启用免费配送。例如,以下代码片段将记录免费配送是否可用:
/**
* 记录免费配送是否可用。
*
* @param bool $is_available 如果免费配送可用,则为 `true`,否则为 `false`。
*
* @return bool
*/
function fsc_free_shipping_is_available( $is_available ) {
if ( $is_available ) {
error_log( '免费配送可用' );
} else {
error_log( '免费配送不可用' );
}
return $is_available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'fsc_free_shipping_is_available', 10, 1 );
需要在每个分类/产品基础上启用配送方法,分割订单,或其他场景?
需要更多灵活性?请查看我们的 高级配送方法扩展。
适用于旧版本地自提的高级设置和自定义
禁用本地自提时的本地税费
默认情况下,本地自提根据您的商店的位置(地址)计算税费,而不是客户的地址。要使用您的标准税费配置,请将以下代码片段添加到您主题的 functions.php 文件的末尾:
add_filter( 'woocommerce_apply_base_tax_for_local_pickup', '__return_false' );
当选择本地自提时,将使用常规税费,而不是基于商店位置的税费。
更改本地自提的税费位置
要根据本地自提位置的邮政编码和城市收取本地税费,您需要使用以下示例代码定义商店的基本城市和邮政编码:
add_filter( 'woocommerce_countries_base_postcode', create_function( '', 'return "80903";' ) );
add_filter( 'woocommerce_countries_base_city', create_function( '', 'return "COLORADO SPRINGS";' ) );
将 80903 更新为您首选的邮政编码,并将 COLORADO SPRINGS 更新为您首选的城镇或城市。
本地自提的自定义邮件
当使用本地自提作为配送方法时,配送地址 不会显示在管理员的订单邮件中。
由于所有核心配送选项都使用标准的订单流程,因此无论客户选择本地自提还是其他任何配送选项,他们都会收到相同的订单确认邮件。 如果您希望为本地自提订单发送单独的邮件,请使用本指南创建自定义邮件:如何添加自定义 WooCommerce 邮件。
向已记录的数据添加链接
日志 是任何 WooCommerce 扩展的重要组成部分。它可以帮助您跟踪错误和调试问题。一种常见的模式是在您的扩展中提供一个设置,以便在用户需要进行故障排除时启用日志记录。以下代码片段展示了如何添加此设置以及指向日志查看器的链接,这在 Settings API 的上下文中非常有用。
use Automattic\WooCommerce\Utilities\LoggingUtil;
// 定义日志记录选项的标签和描述
$label = __( '启用日志', 'your-textdomain-here' );
$description = __( '记录事件和错误,以帮助进行故障排除。', 'your-textdomain-here' );
// 检查 WooCommerce 的日志记录功能是否已启用。
if ( LoggingUtil::logging_is_enabled() ) {
// 用于您扩展的日志条目的源值。可以与您的文本域相同。
$source = 'yourpluginslug';
$logs_url = add_query_arg(
'source',
$source,
LoggingUtil::get_logs_tab_url()
);
$label .= ' | ' . sprintf(
__( '<a href="%s">查看日志</a>', 'your-textdomain-here' ),
$logs_url
);
}
// 将日志记录选项添加到表单字段。
$form_fields['yourpluginslug_debug'] = array(
'title' => __( '调试', 'your-textdomain-here' ),
'label' => $label,
'description' => $description,
'type' => 'checkbox',
'default' => 'no'
);
确保您的翻译升级安全
与其他所有插件一样,WooCommerce 将翻译文件保存在 wp-content/languages/plugins 目录中。
但是,如果您想包含自定义翻译,您可以将它们添加到 wp-content/languages/woocommerce 目录,或者您可以使用一段代码来加载存储在其他位置的自定义翻译:
// 代码应放置在您主题的 functions.php 文件或自定义插件文件中。
add_filter( 'load_textdomain_mofile', 'load_custom_plugin_translation_file', 10, 2 );
/*
* 将 'textdomain' 替换为您的插件的文本域名。例如,'woocommerce'。
* 文件的命名方式,例如,yourtranslationfile-en_GB.mo
* 文件的放置位置,例如,wp-content/lanaguages/textdomain/yourtranslationfile-en_GB.mo
*/
function load_custom_plugin_translation_file( $mofile, $domain ) {
if ( 'textdomain' === $domain ) {
$mofile = WP_LANG_DIR . '/textdomain/yourtranslationfile-' . get_locale() . '.mo';
}
return $mofile;
}
修改显示的相关产品数量
将代码添加到您子主题的 functions.php 文件中,或者通过一个允许添加自定义函数的插件,例如 Code snippets 插件。 避免直接将自定义代码添加到父主题的 functions.php 文件中,因为在更新主题时,这些代码会被清除。
请注意,这对于所有主题都可能不适用,因为它们的代码实现方式不同。
if ( ! function_exists( 'YOUR_PREFIX_related_products_args' ) ) {
/**
* 修改输出的相关产品数量。
*
* @param array $args 相关产品的参数。
* @return array 修改后的相关产品参数。
*/
function YOUR_PREFIX_related_products_args( $args ) {
if ( ! is_array( $args ) ) {
$args = array();
}
$args['posts_per_page'] = 4; // 显示 4 个相关产品。
$args['columns'] = 2; // 按照 2 列排列。
return $args;
}
}
add_filter( 'woocommerce_output_related_products_args', 'YOUR_PREFIX_related_products_args', 20 );
覆盖循环模板,并在“加入购物车”按钮旁边显示数量
将以下代码添加到您子主题的 functions.php 文件中,或者通过允许添加自定义函数的插件,例如 Code Snippets 插件。 避免直接将自定义代码添加到父主题的 functions.php 文件中,因为在更新主题时,这些代码会被完全清除。
if ( ! function_exists( 'YOUR_PREFIX_quantity_inputs_for_woocommerce_loop_add_to_cart_link' ) ) {
/**
* 覆盖循环模板,并在“加入购物车”按钮旁边显示数量
* @param string $html 默认循环模板。
* @param object $product 产品数据。
* @return string 修改后的循环模板。
*/
function YOUR_PREFIX_quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
$html = '<form action="' . esc_url( $product->add_to_cart_url() ) . '" class="cart" method="post" enctype="multipart/form-data">';
$html .= woocommerce_quantity_input( array(), $product, false );
$html .= '<button type="submit" class="button alt">' . esc_html( $product->add_to_cart_text() ) . '</button>';
$html .= '</form>';
}
return $html;
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'YOUR_PREFIX_quantity_inputs_for_woocommerce_loop_add_to_cart_link', 10, 2 );
}
重命名一个国家
在您的国家列表中重命名一个国家:
if ( ! function_exists( 'YOUR_PREFIX_rename_country' ) ) {
/**
* 重命名一个国家
*
* @param array $countries 现有国家名称
* @return array $countries 已更新的国家名称(们)
*/
function YOUR_PREFIX_rename_country( $countries ) {
$countries['IE'] = __( '爱尔兰 (已更改)', 'YOUR-TEXTDOMAIN' );
return $countries;
}
add_filter( 'woocommerce_countries', 'YOUR_PREFIX_rename_country' );
}
SSL 和 HTTPS 和 WooCommerce
位于负载均衡器或反向代理后的网站
WooCommerce 使用 is_ssl() WordPress 函数来验证您的网站是否使用 SSL。
is_ssl() 检查连接是否通过 HTTPS 或在端口 443 上。 但是,这对于位于负载均衡器后面的网站(尤其是托管在 Network Solutions 上的网站)不起作用。 详情请阅读 WordPress is_ssl() 函数参考说明。
可以通过将以下代码添加到 wp-config.php 文件中,在 require_once 调用之前,来修复位于支持 HTTP_X_FORWARDED_PROTO 的负载均衡器或反向代理后面的网站:
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
$_SERVER['HTTPS'] = 'on';
}
注意: 如果您使用 CloudFlare,则需要进行配置。 请查看他们的文档。
移除和禁用 WooCommerce 邮件
这段代码允许您移除和禁用默认的 WooCommerce 邮件。
if ( ! function_exists( 'YOUR_PREFIX_unhook_woocommerce_emails' ) ) {
/**
* 回调函数,用于 woocommerce_email 动作钩子
*
* @param WC_Email $email_class 一个邮件类实例。
* @return void
*/
function YOUR_PREFIX_unhook_woocommerce_emails( $email_class ) {
/**
* 在商店事件期间发送邮件的钩子。
*/
remove_action( 'woocommerce_low_stock_notification', array( $email_class, 'low_stock' ) );
remove_action( 'woocommerce_no_stock_notification', array( $email_class, 'no_stock' ) );
remove_action( 'woocommerce_product_on_backorder_notification', array( $email_class, 'backorder' ) );
// 新增 订单 邮件。
remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_pending_to_completed_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_failed_to_processing_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_failed_to_completed_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
// 处理中 订单 邮件。
remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_Customer_Processing_Order'], 'trigger' ) );
remove_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $email_class->emails['WC_Email_Customer_On_Hold_Order'], 'trigger' ) );
// 已完成 订单 邮件。
remove_action( 'woocommerce_order_status_completed_notification', array( $email_class->emails['WC_Email_Customer_Completed_Order'], 'trigger' ) );
// 备注 邮件。
remove_action( 'woocommerce_new_customer_note_notification', array( $email_class->emails['WC_Email_Customer_Note'], 'trigger' ) );
}
}
add_action( 'woocommerce_email', 'YOUR_PREFIX_unhook_woocommerce_emails' );
卸载并移除所有 WooCommerce 数据
WooCommerce 插件可以像任何其他 WordPress 插件一样进行卸载。 默认情况下,WooCommerce 数据会保留在原位。
如果需要移除所有 WooCommerce 数据,包括产品、订单数据、优惠券等,则需要在停用和删除 WooCommerce 插件之前,修改站点的 wp-config.php 文件。
由于此操作具有破坏性和永久性,因此提供的信息仅供参考。 WooCommerce 支持无法协助此过程或处理由此产生的结果。
要完全从您的 WordPress 站点移除所有 WooCommerce 数据,请打开 wp-config.php 文件,滚动到文件底部,并在 /* That's all, stop editing. */ 这一行之前,添加以下常量,并将其放在单独的一行上。
define( 'WC_REMOVE_ALL_DATA', true );
/* That's all, stop editing! Happy publishing. */
然后,在将更改保存到文件后,当您停用和删除 WooCommerce 时,其所有数据将从您的 WordPress 站点数据库中移除。

有用的核心函数
WooCommerce 核心函数在前端和后台都可用。 它们位于 includes/wc-core-functions.php 文件中,可以由主题和插件使用。
条件函数
WooCommerce 条件函数用于确定当前的查询/网页。
is_woocommerce
如果当前网页使用了 WooCommerce 模板,则返回 true(购物车和结账是标准网页,使用短代码,因此不包含在内)。
is_woocommerce()
is_shop
当浏览产品类型归档页面(商店)时,返回 true。
is_shop()
is_product
当浏览单个产品时,返回 true。
is_product()
优惠券函数
wc_get_coupon_code_by_id
根据优惠券 ID 获取优惠券代码。
wc_get_coupon_code_by_id( $id )
参数 $id 是优惠券 ID。
wc_get_coupon_id_by_code
根据代码获取优惠券 ID。
wc_get_coupon_id_by_code( $code, $exclude = 0 )
$code 是优惠券代码,$exclude 用于排除 ID(如果正在检查是否存在)。
用户函数
wc_customer_bought_product
检查客户是否购买了某个商品。 检查可以通过电子邮件或用户 ID 或两者同时进行。
wc_customer_bought_product( $customer_email, $user_id, $product_id )
wc_get_customer_total_spent
获取客户的总消费金额。
wc_get_customer_total_spent( $user_id )
$user_id 是客户的用户 ID。
wc_get_customer_order_count
获取客户的总订单数量。
wc_get_customer_order_count( $user_id )
$user_id 是客户的用户 ID。
格式化函数
wc_get_dimension
将 WooCommerce 尺寸单位的测量值 $dimension 转换为目标单位 $to_unit。
wc_get_dimension( $dimension, $to_unit, $from_unit = '' )
示例用法:
wc_get_dimension( 55, 'in' );
wc_get_dimension( 55, 'in', 'm' );
wc_get_weight
将 WooCommerce 重量单位的重量 $weight 转换为目标重量单位 $to_unit。
wc_get_weight( $weight, $to_unit, $from_unit = '' )
示例用法:
wc_get_weight( 55, 'kg' );
wc_get_weight( 55, 'kg', 'lbs' );
wc_clean
使用 sanitize_text_field 清理变量。 数组会递归地进行清理。 非标量值将被忽略。
wc_clean( $var )
wc_price
使用正确的十位小数位数和货币符号格式化传入的价格。
wc_price( $price, $args = array() )
$args 数组包含一个名为 ex_tax_label 的选项;如果为 true,则会附加一个“不含税”的信息。
订单函数
wc_get_orders
此函数是检索订单的标准方法,基于某些参数。 应该使用此函数来检索订单,以便在迁移到自定义表时,函数仍然有效。
wc_get_orders( $args )
wc_get_order
这是用于返回订单的主要函数,使用 WC_Order_Factory 类。
wc_get_order( $the_order = false )
the_order 参数可以是订单的文章对象或文章 ID。
wc_orders_count
返回特定订单状态的订单数量。
wc_orders_count( $status, string $type = '' )
wc_order_search
根据给定的 $term 搜索订单。
wc_order_search( $term )
网页函数
wc_get_page_id
根据名称获取 WooCommerce 网页 ID,例如 "thankyou"。
wc_get_page_id( $page )
wc_get_endpoint_url
获取 $endpoint 的 URL,该 URL 会根据固定链接设置而变化。
wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' )
产品函数
wc_get_products
此函数是基于某些参数检索产品的标准方法。
wc_get_products( $args )
wc_get_product
这是用于返回产品的核心函数。它使用 WC_Product_Factory 类。
wc_get_product( $the_product = false )
$the_product 参数可以是产品的文章对象或文章 ID。
wc_get_product_ids_on_sale
返回一个包含正在促销中的产品 ID 的数组。
wc_get_product_ids_on_sale()
wc_get_featured_product_ids
返回一个包含精选产品 ID 的数组。
wc_get_featured_product_ids()
wc_get_related_products
获取基于产品分类和标签的产品相关产品。
wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array() )
账户函数
wc_get_account_endpoint_url
获取账户端点 URL。
wc_get_account_endpoint_url( $endpoint )
属性函数
wc_get_attribute_taxonomies
获取产品属性的分类法。
wc_get_attribute_taxonomies()
wc_attribute_taxonomy_name
获取给定产品属性的分类法名称。
wc_attribute_taxonomy_name( $attribute_name )
wc_attribute_taxonomy_id_by_name
根据名称获取产品属性 ID。
wc_attribute_taxonomy_id_by_name( $name )
REST 函数
wc_rest_prepare_date_response
解析并格式化日期,符合 ISO8601/RFC3339 标准。
wc_rest_prepare_date_response( $date, $utc = true )
将 $utc 参数设置为 false 以获取本地/偏移时间。
wc_rest_upload_image_from_url
从给定的 URL 上传图像。
wc_rest_upload_image_from_url( $image_url )
wc_rest_urlencode_rfc3986
根据 RFC 3986 对 $value 进行编码。
wc_rest_urlencode_rfc3986( $value )
wc_rest_check_post_permissions
检查 REST API 上文章的权限。
wc_rest_check_post_permissions( $post_type, $context = 'read', $object_id = 0 )
$context 参数的可选值,表示请求的上下文,包括 read(已读)、create(创建)、edit(编辑)、delete(删除)和 batch(批量)。
使用 NGINX 服务器保护您的上传目录
如果您使用 NGINX 服务器作为您的站点,并且使用了 X-Accel-Redirect/X-Sendfile 或 Force Downloads 下载方法,则需要添加以下配置以提高安全性:
# 保护 WooCommerce 上传文件夹,防止直接访问。
# 如果您使用的是 "X-Accel-Redirect/X-Sendfile" 或 "Force Downloads" 方法来提供可下载的产品,您可能需要修改此配置。
# 将此配置放置在 NGINX 配置中的 "server" 块的末尾。
location ~* /wp-content/uploads/woocommerce_uploads/ {
if ( $upstream_http_x_accel_redirect = "" ) {
return 403;
}
internal;
}
以下是如果您使用 Redirect only 下载方法时的配置:
# 保护 WooCommerce 上传文件夹,防止直接访问。
# 如果您使用的是 "Redirect Only" 方法来提供可下载的产品,您可能需要修改此配置。
# 将此配置放置在 NGINX 配置中的 "server" 块的末尾。
location ~* /wp-content/uploads/woocommerce_uploads/ {
autoindex off;
}
如果您不确定您使用的是哪种 Web 服务器,请联系您的主机提供商,并提供指向此支持页面的链接。
0135-code-snippets-docs-add-or-modify-states
title: "添加或修改州/省" post_status: publish comment_status: open taxonomy: category: - woocommerce post_tag: - Code Snippets - Repos - Data
post_title: 添加或修改州/省
添加或修改州/省
在 WooCommerce 中,您可以添加自己的州/省信息,或修改现有的州/省信息。
注意:您必须将 XX 替换为您的国家/地区代码。这意味着数组中的每个州/省 ID 必须在您分配给该州/省的数值前面加上您的两个字母的国家/地区代码。
if ( ! function_exists( 'YOUR_PREFIX_add_or_modify_states' ) ) {
/**
* 添加或修改州/省
*
* @param array $states 现有的国家/地区州/省信息。
* @return array $states 修改后的国家/地区州/省信息。
*/
function YOUR_PREFIX_add_or_modify_states( $states ) {
$states['XX'] = array(
'XX1' => __( 'State 1', 'YOUR-TEXTDOMAIN' ),
'XX2' => __( 'State 2', 'YOUR-TEXTDOMAIN' ),
);
return $states;
}
add_filter( 'woocommerce_states', 'YOUR_PREFIX_add_or_modify_states' );
}
检查付款方式是否支持退款、订阅或预购
如果某个付款方式的文档没有明确说明支持的功能,您通常可以通过查看付款方式的代码来了解支持哪些功能。
付款方式可以添加对 WooCommerce 及其扩展的某些功能的支持。例如,付款方式可以支持退款、订阅或预购功能。
Simplify Commerce 示例
以 Simplify Commerce 付款方式为例,在您喜欢的编辑器中打开插件文件并搜索 $this->supports。您将找到支持的功能:
class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway {
/** * 构造函数 */
public function __construct() {
$this->id
= 'simplify_commerce';
$this->method_title
= __( 'Simplify Commerce', 'woocommerce' );
$this->method_description = __( '通过 Simplify Commerce 接收付款 - 使用 simplify.js 创建卡令牌和 Simplify Commerce SDK。当沙盒禁用时需要 SSL。', 'woocommerce' );
$this->has_fields = true;
$this->supports = array(
'subscriptions',
'products',
'subscription_cancellation',
'subscription_reactivation',
'subscription_suspension',
'subscription_amount_changes',
'subscription_payment_method_change',
'subscription_date_changes',
'default_credit_card_form',
'refunds',
'pre-orders'
);
如果您在插件文件中没有找到 $this->supports,这可能意味着该付款方式没有正确声明对退款、订阅或预购的支持。
以编程方式禁用市场场所建议功能
对于那些希望通过编程方式禁用从 woocommerce.com 获取的市场场所建议功能的用户,请将 woocommerce_allow_marketplace_suggestions 过滤器添加到您的主题的 functions.php 文件或自定义插件中。
例如:
add_filter( 'woocommerce_allow_marketplace_suggestions', '__return_false' );
此过滤器将完全从您的 WooCommerce 管理员界面移除市场场所建议功能。
重命名一个国家
在您的国家列表中重命名一个国家:
if ( ! function_exists( 'YOUR_PREFIX_rename_country' ) ) {
/**
* 重命名一个国家
*
* @param array $countries 现有国家名称
* @return array $countries 已更新的国家名称(们)
*/
function YOUR_PREFIX_rename_country( $countries ) {
$countries['IE'] = __( '爱尔兰 (已更改)', 'YOUR-TEXTDOMAIN' );
return $countries;
}
add_filter( 'woocommerce_countries', 'YOUR_PREFIX_rename_country' );
}
CSS SASS 编码规范和命名约定
我们的规范基于 Calypso 所使用的规范,而 Calypso 本身遵循 BEM 方法论。请参考 此文档 获取完整详情。但是,WooCommerce 存在一些差异,具体内容如下:
前缀
由于 WooCommerce 是一个 WordPress 插件,因此必须与 WordPress 核心以及其他插件/主题兼容。为了最大限度地减少潜在冲突,所有类都应以 .woocommerce- 开头。
类名
Calypso 是使用 React 构建的,并使用组件名称来构建 CSS 类名。WooCommerce 核心没有这些组件,因此使用更传统的 BEM 方法来 命名类。
在添加类时,请记住以下内容:
- Block - 独立的实体,本身具有意义。
- Element - 块的组成部分,没有独立的意义。它们在语义上与块相关联。
- Modifier - 块或元素的标志。使用它们来更改外观或行为。
示例
.woocommerce-loop {}(块)。.woocommerce-loop-product {}(嵌套块)。.woocommerce-loop-product--sale {}(修饰符)。.woocommerce-loop-product__link {}(元素)。.woocommerce-loop-product__title {}(元素)。.woocommerce-loop-product__price {}(元素)。.woocommerce-loop-product__rating {}(元素)。.woocommerce-loop-product__button-add-to-cart {}(元素)。.woocommerce-loop-product__button-add-to-cart--added {}(修饰符)。
注意: .woocommerce-loop-product 不是选定的类名,因为 该块嵌套在 .woocommerce-loop 中。这是为了更具体,以便我们可以为单个产品、购物车产品等设置单独的类。嵌套块不需要继承其父级的全名。
您可以阅读有关 BEM 关键概念的更多信息,请参考 BEM 方法论文档。
简而言之
- 遵循 WordPress CSS 编码规范,除非它与此处的内容相矛盾。
- 遵循 Calypso 指南。
- 使用 BEM 进行 类名 的定义。
- 为所有内容添加前缀。
WooCommerce 核心 API 中的关键流程
在我们的文档中,我们已经确定了 WooCommerce 核心 API 中的关键用户流程。这些流程是我们测试工作的指南,帮助我们集中精力在最重要的方面。它们也为评估修改的影响以及确定问题优先级提供了宝贵的见解。
需要注意的是,这些流程是动态的,会随着平台的发展而不断演变。它们会定期进行更新、添加和重新排序,以适应我们系统不断变化的需求。
产品
| 路由 | 流程名称 | 接口 | 测试文件 |
|---|---|---|---|
| 产品 | 可以查看所有产品 | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/product-list.test.js |
| 产品 | 可以搜索产品 | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/product-list.test.js |
| 产品 | 可以添加一个简单产品 | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| 产品 | 可以添加一个可变产品 | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| 产品 | 可以添加一个虚拟产品 | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| 产品 | 可以查看单个产品 | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
| 产品 | 可以更新产品 | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
| 产品 | 可以删除产品 | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
订单
| 路由 | 流程名称 | 接口地址 | 测试文件 |
|---|---|---|---|
| 订单 | 可以创建订单 | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| 订单 | 可以查看单个订单 | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| 订单 | 可以更新订单 | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| 订单 | 可以删除订单 | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| 订单 | 可以查看所有订单 | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/orders.test.js |
| 订单 | 可以搜索订单 | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/order-search.test.js |
| 订单 | 可以新增复杂订单 - 包含多种产品类型和税类 | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/order-complex.test.js |
退款
| 路由 | 流程名称 | 接口地址 | 测试文件 |
|---|---|---|---|
| 退款 | 可以退款订单 | /wp-json/wc/v3/orders/{id}/refunds |
tests/api-core-tests/tests/refunds/refund.test.js |
优惠券
| 路由 | 流程名称 | 接口地址 | 测试文件 |
|---|---|---|---|
| 优惠券 | 可以创建优惠券 | /wp-json/wc/v3/coupons |
tests/api-core-tests/tests/coupons/coupons.test.js |
| 优惠券 | 可以更新优惠券 | /wp-json/wc/v3/coupons/{id} |
tests/api-core-tests/tests/coupons/coupons.test.js |
| 优惠券 | 可以删除优惠券 | /wp-json/wc/v3/coupons/{id} |
tests/api-core-tests/tests/coupons/coupons.test.js |
| 优惠券 | 可以将优惠券添加到订单 | /wp-json/wc/v3/orders/{id}/coupons |
tests/api-core-tests/tests/coupons/coupons.test.js |
配送
| 路线 | 流程名称 | 接口 | 测试文件 |
|---|---|---|---|
| 配送区域 | 可以创建配送区域 | /wp-json/wc/v3/shipping/zones |
tests/api-core-tests/tests/shipping/shipping-zones.test.js |
| 配送方式 | 可以为配送区域创建配送方式 | /wp-json/wc/v3/shipping/zones/{id}/methods |
n/a |
| 配送类型 | 可以创建产品配送类型 | /wp-json/wc/v3/products/shipping_classes |
tests/api-core-tests/tests/products/products-crud.test.js |
Shipping Classes
This document describes how to use the API to manage Shipping Classes.
Creating a Shipping Class
To create a new Shipping Class, you can use the following API endpoint:
POST /wp-json/wc/v3/products/shipping_classes
The request body should contain the following parameters:
name: The name of the Shipping Class.description: A description of the Shipping Class.method_id: The ID of the Shipping Method to associate with the Shipping Class.
For example:
{
"name": "Expedited Shipping",
"description": "Faster shipping option",
"method_id": 123
}
Updating a Shipping Class
To update an existing Shipping Class, you can use the following API endpoint:
PUT /wp-json/wc/v3/products/shipping_classes/%d
where %d is the ID of the Shipping Class you want to update.
The request body should contain the parameters you want to update.
Deleting a Shipping Class
To delete a Shipping Class, you can use the following API endpoint:
DELETE /wp-json/wc/v3/products/shipping_classes/%d
where %d is the ID of the Shipping Class you want to delete.
Example Usage
Here is an example of how to create a new Shipping Class using the API:
import requests
url = "https://example.com/wp-json/wc/v3/products/shipping_classes"
headers = {"Content-Type": "application/json"}
data = {
"name": "Expedited Shipping",
"description": "Faster shipping option",
"method_id": 123
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 201:
print("Shipping Class created successfully!")
print(response.json())
else:
print("Error creating Shipping Class:")
print(response.status_code)
print(response.text)
This example uses the requests library to make an HTTP POST request to the API endpoint. The headers dictionary specifies the Content-Type header, which indicates that the request body is in JSON format. The data dictionary contains the parameters for the new Shipping Class.
The response from the API is checked to see if it was successful. If the status code is 201 (Created), then the Shipping Class was created successfully. The response body contains the details of the new Shipping Class. If the status code is not 201, then an error occurred, and the error message is printed.
Important Considerations
- Make sure you have the necessary permissions to create, update, and delete Shipping Classes.
- The API may require authentication.
- The API may have rate limits.
- Always handle errors gracefully.
This document provides a basic overview of how to use the API to manage Shipping Classes. For more information, please refer to the API documentation.
Testing
The following TEST cases are available for verifying the functionality of the Shipping Classes API:
- Can create a new Shipping Class.
- Can update an existing Shipping Class.
- Can delete a Shipping Class.
- Can retrieve a list of Shipping Classes.
These TEST cases can be run using the tests/api-core-tests/tests/products/products-crud.test.js File.
Troubleshooting
If you are having trouble using the API, please consult the following resources:
- The API documentation
- The online forums
- The support team
If you are still unable to resolve the issue, please contact the support team for assistance.
Error Codes
The following error codes may be returned by the API:
- 400 Bad Request: The request was invalid.
- 401 Unauthorized: You are not authorized to perform this action.
- 403 Forbidden: You do not have permission to perform this action.
- 404 Not Found: The resource you are trying to access does not exist.
- 500 Internal Server Error: An unexpected error occurred on the server.
Pro features may require a paid subscription.
Shipping Zones
You can create Shipping Zones to define different shipping rates for different regions. Each Shipping Zone can have multiple Shipping Methods associated with it.
Shipping Methods
Shipping Methods define how products are shipped. You can create different Shipping Methods for different Shipping Classes and Shipping Zones.
Core functionality is available in the free version.
Low latency is important for a good user experience.
In some cases, you may need to manually configure the Shipping Classes.
This is one example.
Or you can use a different approach.
The value is n/a.
The Name of the Product is required.
The Method is not supported.
The Class is not defined.
常见问题
本页面旨在记录已知的常见问题、遇到的问题以及它们的解决方案或解决方法。 如果您遇到了此处未提及但应该记录的问题,请随时将其添加到列表中。
Composer 在 Automattic\Jetpack\Autoloader\AutoloadGenerator 上的错误
[ErrorException]
Declaration of Automattic\Jetpack\Autoloader\AutoloadGenerator::dump(Composer\Config $config, Composer\Repository\Inst
alledRepositoryInterface $localRepo, Composer\Package\PackageInterface $mainPackage, Composer\Installer\InstallationMa
nager $installationManager, $targetDir, $scanPsrPackages = false, $suffix = NULL) should be compatible with Composer\A
utoload\AutoloadGenerator::dump(Composer\Config $config, Composer\Repository\InstalledRepositoryInterface $localRepo,
Composer\Package\RootPackageInterface $rootPackage, Composer\Installer\InstallationManager $installationManager, $targ
etDir, $scanPsrPackages = false, $suffix = '')
Composer 2.0.7 的一个更改 导致我们的自动加载器与新的 AutoloadGenerator 签名不兼容。 尝试降级到 composer 2.0.6,使用 composer self-update 2.0.6 命令。
VVV: HostsUpdater vagrant 插件错误
...vagrant-hostsupdater/HostsUpdater.rb:126:in ``digest': no implicit conversion of nil into String (TypeError)
您可能正在运行不受支持的 Vagrant 版本。 撰写本文时,VVV 与 Vagrant 2.2.7 兼容。 请检查 VVV 的要求。
VVV: install-wp-tests.sh 错误
mysqladmin: CREATE DATABASE failed; error: 'Access denied for user 'wp'@'localhost' to database 'wordpress-one-tests''
解决方法:
- 使用
sudo mysql打开 MySQL。 - 运行
GRANT ALL PRIVILEGES ON * . * TO 'wp'@'localhost';。 通过输入exit;退出。 - 再次运行
install-wp-tests.sh脚本。
运行端到端测试时出现超时/404 错误
Store owner can complete onboarding wizard › can complete the product types section
TimeoutError: waiting for function failed: timeout 30000ms exceeded
1 | export const waitForElementCount = function ( page, domSelector, count ) {
> 2 | return page.waitForFunction(
| ^
3 | ( domSelector, count ) => {
4 | return document.querySelectorAll( domSelector ).length === count;
5 | },
端到端测试中的超时或 404 错误表明现有的构建可能已损坏。 运行 npm install && npm run clean && npm run build 以生成一个全新的构建。 值得注意的是,我们的某些 npm 脚本也会删除当前的构建,因此,在运行端到端测试之前,始终构建是一个好习惯。
Docker 容器构建失败,导致端到端测试无法执行
Thu Dec 3 11:55:56 +08 2020 - Docker 容器正在构建中
Thu Dec 3 11:56:06 +08 2020 - Docker 容器正在构建中
Thu Dec 3 11:56:16 +08 2020 - Docker 容器正在构建中
Thu Dec 3 11:56:26 +08 2020 - Docker 容器构建失败
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @woocommerce/e2e-environment@0.1.6 test:e2e: `bash ./bin/wait-for-build.sh && ./bin/e2e-test-integration.js`
npm ERR! Exit status 1
请确保 Docker 正在运行。虽然脚本显示“Docker 容器正在构建中”,但它实际上并不负责运行 Docker;它只是等待现有的 Docker 实例做出响应。如果未运行,请运行 npm run docker:up。
设置 WooCommerce Payments 开发模式
将以下内容添加到 wp-config.php:
define( 'WCPAY_DEV_MODE', true );
另请参阅 此文档。
获取 WooCommerce 管理员安装时间戳
要获取安装时间戳(例如,在 NoteTraits 中的 wc_admin_active_for() 函数中),请尝试以下 SQL 语句:
SELECT * FROM wp_options WHERE option_name = 'woocommerce_admin_install_timestamp'
重置引导向导
删除 woocommerce_onboarding_profile 选项:
DELETE FROM wp_options WHERE option_name = 'woocommerce_onboarding_profile'
启用控制台中的跟踪调试
localStorage.setItem( 'debug', 'wc-admin:tracks' );
并将 Chrome 的日志级别设置为“详细”(verbose),并选中“已选中”状态。
使用 Vagrant (VVV) 运行 PHP 单元测试
- 通过 SSH 连接到 Vagrant 虚拟机 (
vagrant ssh) cd /srv/www/<WP_INSTANCE>/public_html/wp-content/plugins/woocommerce-admin- 执行设置:
bin/install-wp-tests.sh wc-admin-tests root root - 快速测试:
./vendor/bin/phpunit --group fast - 所有测试:
./vendor/bin/phpunit
如果 phpunit 不存在,您可能需要运行 composer install。
如何评估 Pull Request 的影响
判断一个 Pull Request 是否应该被标记为“高影响”是一项复杂的任务。为了实现这一点,我们需要评估和估算 Pull Request 中引入的更改对 WooCommerce 的影响,这通常是一项主观的任务,并且有时会不准确,因为这需要对 WooCommerce 产品细节、技术细节,甚至客户问题历史有深入的了解。
在本页面,我们将分享一些指南,以帮助您评估 Pull Request 的影响程度。
您应该将 Pull Request 标记为“高影响”的情况:
- 它为 WooCommerce 添加了新功能,除非该功能位于特性开关 (feature flag) 后面。
- 它修改了关键功能(请参阅 关键流程列表)。
- 它修复了一个高优先级 bug(这包括修复 Blocks 的 bug 以及核心版本的更新)。
- 它包含安全修复。
- 它更新了SQL 查询。
- 它涉及任何
$_REQUEST变量。 - 任何类型的数据迁移/更新。
- 更改了 WooCommerce 发送的邮件。
- 更改了 WooCommerce 的钩子/操作/过滤器。
- 更改了 REST API 端点。
- 这是一个大型 PR(即,它在许多文件中添加了多个更改)。
- 它包含国际化 (i18n) 更改(例如,
woocommerce/i18n目录下的任何文件被修改)。
您不应该将 Pull Request 标记为“高影响”的情况:
- 它仅更新了自动化测试,与 WooCommerce 发布包中不包含的基础设施相关的内容,或 monorepo 中未包含在发布包中的其他项目。
- 它仅包含文档 (readme) 或变更日志 (changelog) 的更改。
- 修复了一个低优先级的 bug,例如拼写错误等。
- 不需要验证在多种环境类型中。
- 定期计划的(非修复版本)核心版本的更新,适用于 Blocks 包(因为测试已经安排)。
- 它是尚未完整发布的产品的一部分(即,它当前位于特性开关 (feature flag) 后面,处于进行中状态)。
我的 PR 是高影响的。接下来该怎么办?
如果您的 PR 是高影响的,请务必使用 impact: high 标签,WooCommerce 核心团队将对此进行特殊的测试考虑。
核心功能的弃用
弃用是一种鼓励用户放弃某些功能或实践,而选择其他替代方案的方法,这种方法既不破坏向后兼容性,也不完全禁止其使用。 引用维基百科关于弃用的文章:
尽管已弃用的软件功能仍然存在于软件中,但其使用可能会引发警告消息,建议采用替代方案;弃用状态也可能表明该功能将在未来被移除。 为了提供向后兼容性,并为程序员提供时间来使受影响的代码符合新的标准,因此会先弃用功能,而不是立即删除。
有各种原因可能导致某个函数、方法或功能被弃用。 举例来说:
- 我们可能希望移除不再使用的函数。
- 我们可能决定更改或改进某个函数的工作方式,但由于会破坏向后兼容性,因此我们需要弃用旧的函数。
- 我们可能希望标准化命名约定。
- 我们可能会发现可以合并相似功能的机会,以避免在不同的地方重复使用相同的代码。
虽然弃用通知不太理想或美观,但它们仅仅是_警告_,而不是_错误_。
商店所有者: 弃用警告并不意味着您的商店已损坏,它只是提醒您需要更新代码。
我们如何弃用函数?
当我们在 WooCommerce 中弃用某些内容时,我们会采取一些措施,以便清楚地告知开发者,并保持向后兼容性。
- 我们会在函数或方法中添加文档块,说明该函数在哪个版本中被弃用,例如:
@deprecated 2.x.x。 - 我们会使用我们自己的
wc_deprecated_function函数添加警告通知,该通知显示了哪个版本、哪个函数以及可用的替代方案。 稍后会详细介绍。 - 我们会移除整个代码库中对已弃用函数的引用。
该函数或方法本身不会从代码库中删除。 这样可以保持向后兼容性,直到被移除——通常是在一年或几个主要版本之后。
我们上面提到了 wc_deprecated_function,这是一个我们自己的 _deprecated_function WordPress 函数的包装器。 它的工作方式非常相似,只是它会强制记录条目,而不是显示它——无论在 AJAX 事件期间 WP_DEBUG 的值是多少——这样可以防止 AJAX 请求因该通知而中断。
当调用已弃用的函数时会发生什么?
如果某个扩展或主题使用了已弃用的函数,您可能会看到如下所示的警告:
Notice: woocommerce_show_messages 已在版本 2.1 中被弃用!请使用 wc_print_notices 代替。位于 /srv/www/wordpress-default/wp-includes/functions.php 第 3783 行
这会告诉您哪个函数已被弃用,自何时起,位于何处,以及有哪些可用的替代方案。
通常,Notice 和 Warning 会在页面上显示,但有一些插件可以帮助您收集并将它们以美观的方式显示在网站的页脚中。例如,您可以考虑使用 Query Monitor。
生产环境中的警告(店主 - 请阅读!)
强烈建议不要在您的生产环境中显示 PHP Notice 和 Warning(或者任何 Error)。 它们可能会泄露有关您配置的信息,而恶意用户可能会利用这些信息来访问您的商店。 确保它们对公众隐藏,并可以选择将其记录下来。
在 WordPress 中,您可以通过在 wp-config.php 文件中添加或修改一些常量来实现这一点:
define( 'WP_DEBUG', false );
在某些主机上,由于主机的配置,Error 可能仍然可见。 为了强制它们不显示,您可能需要在 wp-config.php 文件中添加以下内容:
@ini_set( 'display_errors', 0 );
要记录 Notice 而不是显示它们,请使用以下代码:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
WordPress 错误日志的默认位置是 wp-content/debug.log。
请注意,此日志可能对公众可见,这可能会带来安全风险。 为了使其保持私有,您可以使用插件或在 wp-config.php 文件中定义自定义路径。
<?php
/**
* 插件名称: 自定义调试日志路径
*/
ini_set( 'error_log', '/path/to/site/logs/debug.log' );
处理 WooCommerce 中的 SCSS 和 JS 压缩
SCSS
当在 WooCommerce 项目中更新 SCSS 文件时,请仅提交您对未压缩的 SCSS 文件的更改。 压缩操作将作为发布过程的一部分进行处理。
要获取压缩后的 CSS 文件,请从仓库根目录运行 pnpm --filter='@woocommerce/classic-assets' build 命令。 要从头开始设置开发环境,请参阅关于 如何安装依赖项和生成资源 的部分,该部分是设置 WooCommerce 开发环境的指南。
Javascript
当更改 JS 文件时,请仅提交未压缩的文件(即,可读的 JS 文件)。 压缩操作将作为发布过程的一部分进行处理。
为了确保您可以测试您的更改,请使用 SCRIPT_DEBUG 模式运行,即,在您的 wp-config.php 文件中添加 define( 'SCRIPT_DEBUG', true );。
命名规范
PHP
WooCommerce 核心通常遵循 WordPress PHP 命名规范。此外,函数、类和钩子名称应添加前缀。对于函数,前缀为 wc_;对于类,前缀为 WC_;对于钩子,前缀为 woocommerce_。
函数名称示例:
wc_get_product()wc_is_active_theme()
类名称示例:
钩子名称示例(操作或过滤器):
woocommerce_after_checkout_validationwoocommerce_get_formatted_order_total
但是,对于在 src/ 目录中定义的类,有一些例外。在该目录中:
- 我们不为类名称使用
WC_前缀(因为所有这些类都位于Automattic\WooCommerce命名空间中,因此不需要前缀)。 - 类名称使用
CamelCase约定(但是,方法名称仍然应使用underscore_separated格式)。 - 类文件应与类名称匹配,并且不需要
class-前缀(例如,StringUtil类的文件名是StringUtil.php)。
JS
WooCommerce 核心遵循 WordPress JS 命名规范。与 PHP 类似,函数、类和钩子名称应添加前缀,但 JS 的约定略有不同,并且使用 camelCase 而不是 snake_case。对于函数,前缀为 wc;对于类,前缀为 WC;对于钩子,前缀为 woocommerce。
函数名称示例:
wcSettings()
类名称示例:
WCOrdersTable
钩子名称示例(操作或过滤器):
woocommerceTracksEventProperties
CSS 和 SASS
请参阅 CSS SASS 编码指南和命名规范。
报告安全问题
WooCommerce 非常重视安全性,并努力确保我们的商家及其客户的安全。
您可以在 这里 找到我们的安全策略,如果您认为您发现了一个漏洞,我们鼓励您遵循该策略并通过 HackerOne 提交您的发现。HackerOne 是一个值得信赖的第三方服务,用于报告安全问题。请参考该策略以获取更多详情,但以下是一些关键点:
- 我们运营一个 漏洞奖励计划,因此您可以因有效的报告而获得奖励,但并非所有内容都在范围内。请在发布前查看指南。
- 我们强烈鼓励 负责任的披露。为了更好地保护所有人,请使用 HackerOne,不要在公共论坛上发布您的发现。
谢谢您作为负责任的报告者!
字符串本地化指南
- 在所有字符串中使用
woocommercetextdomain。 - 当在
printf/sprintf中使用动态字符串时,如果需要替换多个字符串,请使用编号参数。例如,Test %s string %s.应该改为Test %1$s string %2$s. - 使用句首字母大写形式。例如,
Some Thing应该改为Some thing。 - 避免使用 HTML。如果需要,请使用
sprintf插入 HTML。
更多信息,请参阅 WordPress 核心文档 i18n for WordPress Developers。
WooCommerce Git Flow
约定
分支命名
虽然我们不强制执行任何命名约定,除了发布分支(始终以 release/ 开头),但前缀有助于指示分支或更改的类型。 一些常见的前缀包括 fix/、feature/、add/ 和 update/。
特别是,在创建 修复分支 时,请使用正确的前缀和问题编号(例如,fix/12345)或总结更改(例如,fix/12345-shipping-tax-rate-saving)。
发布
对于核心开发,我们使用以下结构和流程。

请参考 发布计划 文档,以获取更多详情。
WooCommerce Core API 中的关键流程
在说明文档中,我们已明确指出了 WooCommerce Core API 中的核心用户流程。这些流程为我们的测试工作提供了指引,帮助我们集中精力于最重要的环节。它们还为评估修改影响和确定问题优先级提供了宝贵的参考。
需要注意的是,这些流程是动态的,会随着平台的发展而同步演进。它们会定期进行更新、增补和优先级调整,以保持与系统不断变化的需求对齐。
Products
| Route | Flow name | Endpoint | Test File |
|---|---|---|---|
| Products | Can view all products | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/product-list.test.js |
| Products | Can search products | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/product-list.test.js |
| Products | Can add a simple product | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| Products | Can add a variable product | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| Products | Can add a virtual product | /wp-json/wc/v3/products |
tests/api-core-tests/tests/products/products-crud.test.js |
| Products | Can view a single product | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
| Products | Can update a product | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
| Products | Can delete a product | /wp-json/wc/v3/products/{id} |
tests/api-core-tests/tests/products/products-crud.test.js |
Orders
| Route | Flow name | Endpoints | Test File |
|---|---|---|---|
| Orders | Can create an order | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| Orders | Can view a single order | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| Orders | Can update an order | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| Orders | Can delete an order | /wp-json/wc/v3/orders/{id} |
tests/api-core-tests/tests/orders/orders-crud.test.js |
| Orders | Can view all orders | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/orders.test.js |
| Orders | Can search orders | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/order-search.test.js |
| Orders | Can add new Order complex - multiple product types & tax classes | /wp-json/wc/v3/orders |
tests/api-core-tests/tests/orders/order-complex.test.js |
Refunds
| Route | Flow name | Endpoints | Test File |
|---|---|---|---|
| Refunds | Can refund an order | /wp-json/wc/v3/orders/{id}/refunds |
tests/api-core-tests/tests/refunds/refund.test.js |
Coupons
| Route | Flow name | Endpoints | Test File |
|---|---|---|---|
| Coupons | Can create a coupon | /wp-json/wc/v3/coupons |
tests/api-core-tests/tests/coupons/coupons.test.js |
| Coupons | Can update a coupon | /wp-json/wc/v3/coupons/{id} |
tests/api-core-tests/tests/coupons/coupons.test.js |
| Coupons | Can delete a coupon | /wp-json/wc/v3/coupons/{id} |
tests/api-core-tests/tests/coupons/coupons.test.js |
| Coupons | Can add a coupon to order | /wp-json/wc/v3/orders/{id}/coupons |
tests/api-core-tests/tests/coupons/coupons.test.js |
Shipping
| Route | Flow name | Endpoints | Test File |
|---|---|---|---|
| Shipping zones | Can create shipping zones | /wp-json/wc/v3/shipping/zones |
tests/api-core-tests/tests/shipping/shipping-zones.test.js |
| Shipping methods | Can create shipping method to a shipping zone | /wp-json/wc/v3/shipping/zones/{id}/methods |
n/a |
| Shipping classes | Can create a product shipping class | /wp-json/wc/v3/products/shipping_classes |
tests/api-core-tests/tests/products/products-crud.test.js |
处理 WooCommerce 中的 SCSS 和 JS 压缩
SCSS
当在 WooCommerce 项目中更新 SCSS 文件时,请仅提交您对未压缩的 SCSS 文件的更改。 压缩操作将作为发布过程的一部分进行处理。
要获取压缩后的 CSS 文件,请从仓库根目录运行 pnpm --filter='@woocommerce/classic-assets' build 命令。 要从头开始设置开发环境,请参阅关于 如何安装依赖项和生成资源 的部分,该部分是设置 WooCommerce 开发环境的指南。
Javascript
当更改 JS 文件时,请仅提交未压缩的文件(即,可读的 JS 文件)。 压缩操作将作为发布过程的一部分进行处理。
为了确保您可以测试您的更改,请使用 SCRIPT_DEBUG 模式运行,即,在您的 wp-config.php 文件中添加 define( 'SCRIPT_DEBUG', true );。
报告安全问题
WooCommerce 非常重视安全性,并努力确保我们的商家及其客户的安全。
您可以在 这里 找到我们的安全策略,如果您认为您发现了一个漏洞,我们鼓励您遵循该策略并通过 HackerOne 提交您的发现。HackerOne 是一个值得信赖的第三方服务,用于报告安全问题。请参考该策略以获取更多详情,但以下是一些关键点:
- 我们运营一个 漏洞奖励计划,因此您可以因有效的报告而获得奖励,但并非所有内容都在范围内。请在发布前查看指南。
- 我们强烈鼓励 负责任的披露。为了更好地保护所有人,请使用 HackerOne,不要在公共论坛上发布您的发现。
谢谢您作为负责任的报告者!
字符串本地化指南
- 在所有字符串中使用
woocommercetextdomain。 - 当在
printf/sprintf中使用动态字符串时,如果需要替换多个字符串,请使用编号参数。例如,Test %s string %s.应该改为Test %1$s string %2$s. - 使用句首字母大写形式。例如,
Some Thing应该改为Some thing。 - 避免使用 HTML。如果需要,请使用
sprintf插入 HTML。
更多信息,请参阅 WordPress 核心文档 i18n for WordPress Developers。
WooCommerce Git Flow
约定
分支命名
虽然我们不强制执行任何命名约定,除了发布分支(始终以 release/ 开头),但前缀有助于指示分支或更改的类型。 一些常见的前缀包括 fix/、feature/、add/ 和 update/。
特别是,在创建 修复分支 时,请使用正确的前缀和问题编号(例如,fix/12345)或总结更改(例如,fix/12345-shipping-tax-rate-saving)。
发布
对于核心开发,我们使用以下结构和流程。

请参考 发布计划 文档,以获取更多详情。
贡献技术文档
感谢您帮助改进 WooCommerce 的开发者文档。我们的文档由 Docusaurus 提供支持,位于 monorepo 中的 woocommerce/docs/ 文件夹内。
本指南将引导您了解贡献的结构、工具和流程,以便高效地进行贡献。
快速开始
本指南假设您熟悉基本的 Git 和 GitHub 功能,并且您已登录到 GitHub 帐户,并且已在本地配置了 Git。如果您是 GitHub 的新手,我们建议您在开始之前阅读他们的 快速入门 和 使用分支 指南。
初始设置
- 在 GitHub 上 fork WooCommerce monorepo。如果提示,您可以安全地选中
copy the trunk branch only选项。 - 克隆您刚刚创建的分支。这将允许您在本地进行编辑。
进行修改
-
在进行任何修改之前,请确保您的
trunk分支与 monorepo 的trunk同步。 -
对于您想要进行的每项修改,请在您的 fork 中,从
trunk创建一个新的分支,分支名称应以docs/开头。例如,如果您要添加一个关于改进扩展性能的文档,您可以将分支命名为docs/improve-extension-performance。 -
在
docs/下的适当文件夹中创建或编辑 Markdown 文件。 -
如果需要,请更新文件夹的
_category_.json文件(用于侧边栏标签/位置)。 -
运行构建以验证更改,确认站点地图和 llms-txt 文件已更新,并检测 Markdown 语法错误和断开的链接(链接检查仅在构建时进行):
npm run build
打开拉取请求
- 提交并推送到您的 fork。
- 打开一个拉取请求 到 woocommerce/woocommerce,目标分支为
trunk。 - 使用描述性的标题,并填写 PR 模板。包括:
- 新文件或分类的理由
- 关于任何侧边栏或结构更改的说明
- WooCommerce 开发者倡导团队将审查并合并您的更改。
文档文件夹结构
工具和配置
- 支持工具和配置 位于:
- 顶层侧边栏和导航栏 的配置位于:
文档文件
-
文档位置: 所有文档都位于
woocommerce/docs/目录下。 -
每个文件夹代表一个侧边栏或顶层导航的分类,例如:
getting-started、code-snippets等。 -
每个分类的侧边栏配置 使用每个分类文件夹内的
_category_.json文件进行管理:{ "position": 7, "label": "Code snippets" }
添加图像
所有文档图像都存储在:
docs/_docu-tools/static/img/doc_images/
要在 Markdown 文件中包含图像,请按以下方式引用它:

创建新的分类
在创建新的分类之前,您应该考虑是否真的有必要这样做。 尽可能地,应该将内容创建在现有的分类中。 如果确实需要创建新的分类,请按照以下步骤操作:
-
在
/docs文件夹中,创建一个具有描述性名称的子文件夹。 例如,如果您想创建一个Checkout design guidelines部分,则创建一个名为/docs/checkout-design-guidelines的文件夹。 -
在每个分类文件夹中创建一个
_category_.json文件,并指定其在侧边栏中的位置以及标签:{ "position": 10, "label": "Checkout design guidelines" }
在创建新的分类时,请在您的拉取请求的描述中包含创建该分类的理由。
撰写指南和参考
- 使用短的、适合 URL 的文件名(kebab-case,不包含空格)。
- 避免从富文本编辑器(如 Google Docs)粘贴内容,因为这可能会引入无效的字符。
- 请参考我们的 文档风格指南,以获取详细的撰写指南。
- 请参考 Docusaurus 文档,以获取更多指导。
技术文档风格指南
本风格指南旨在提供创建有效且用户友好的 WooCommerce 技术文档的指导方针,这些文档将存储在代码仓库中,并由开源贡献者和 WooCommerce 团队进行编辑和迭代。
写作风格
语言风格
-
重要的是使用清晰简洁的语言,使其易于理解。 使用主动语态,避免使用可能让用户不熟悉的行话或技术术语。 语气应友好且平易近人,并鼓励用户采取行动。
-
文章采用第三人称。 示例:“将一个嵌入块添加到您的网页中。”
-
使用美式英语的拼写和标点符号,或者考虑使用在其他英语变体中没有不同拼写的其他单词。
-
对于文档标题和副标题,使用句首字母大写(而不是全部字母大写)。 示例:“Introduction to the launch experience” 而不是 “Introduction to the Launch Experience”。
-
当引用文件或目录时,文本格式可以消除包含冠词(如“the”)或澄清名词(如“file”或“directory”)的必要性。 示例:“存储在
~/wp-content/uploads/目录中的文件” 或 “使用~/config/config.yml文件”。
写作技巧
-
我们的目标受众具有各种角色和能力。 在创建教程或操作指南时,重要的是要考虑目标受众。 他们是初学者还是高级用户? 他们的技术背景是什么? 了解受众可以帮助指导指南的详细程度和使用的语言。
-
使用即使是那些技术知识有限的读者以及母语不是英语的读者也能理解的语言。
-
考虑这可能是读者看到的第一个 WooCommerce 文档页面。 他们可能通过 Google 搜索或其他网站来到这里。 为读者提供足够的关于该主题的背景信息,并尽可能将单词和短语链接到其他相关的文档文章。
-
考虑添加注释和部分,提供见解、技巧或警告信息,以扩展主题,并提供与读者相关的背景信息。
-
当提供具体的指导、最佳实践或要求时,我们建议包括对未遵循提供的指导可能产生的潜在后果或影响的描述。 这可以帮助在文档中添加额外的搜索关键词,并在支持人员链接到文档时提供更好的上下文。
-
始终首先为该主题编写一个概念性的、高级别的介绍,放在任何 H2 副标题之上。
教程
教程是全面的,旨在教授新的技能或概念。
您是老师,您负责学生的学习内容。 在您的指导下,学生将执行一系列操作以达到某个目标。
实用指南
实用指南是专注于特定主题,提供关于如何完成特定任务或解决特定问题的说明。
实用指南与教程完全不同,切勿混淆:
- 教程是您认为初学者需要了解的内容。
- 实用指南是针对只有具有一定经验的用户才能提出的问题的答案。
自定义代码检查规则
在 WooCommerce,我们致力于维护技术文档的一致性和高质量标准。 我们的文档主要遵循 markdownlint 提供的代码检查规则。 为了帮助我们的贡献者,我们详细介绍了我们的自定义配置和例外情况,如下所示。
注意:虽然我们上面列出了具体的规则,但所有其他默认的代码检查规则都来自 markdownlint,除非另有说明。 我们在此处仅强调自定义配置或例外情况。 要获取 markdownlint 规则的完整列表,您可以参考 此链接。
-
标题样式:
- 使用 ATX 样式 (
#) 来表示标题。
# 这是一个 H1 标题 ## 这是一个 H2 标题 - 使用 ATX 样式 (
-
列表缩进:
- 使用 4 个空格来缩进列表项目。
- 项目 1 - 子项目 1.1 -
行长度:
- 对行长度没有具体的限制,但请确保段落和句子易于阅读。
-
内容相同的多个标题:
- 只要它们不是兄弟标题,允许存在内容相同的多个标题。
-
内联 HTML:
- 仅允许使用
video元素时使用内联 HTML。
<video src="path_to_video.mp4" controls></video> - 仅允许使用
-
制表符和空格:
- 我们对使用硬制表符和尾随空格持开放态度。 但是,为了保持一致性,我们建议使用空格代替制表符,并避免尾随空格。
格式
视觉风格
- 使用 H2 样式作为主要标题,以便在文章的目录中进行程序化列出。
文件名和目录路径应按照 HTML 规范 的规定进行代码化处理。 示例:/wp-content/uploads/- 对单个目录的引用应在名称后添加尾随斜杠 (例如,添加 "/" )。 示例:“uploads/”
- 对代码仓库的引用应不包含前导斜杠,并且不应进行任何格式化。在文章内容中首次出现代码仓库时,应尽可能链接到代码仓库的 URL。 示例:“woocommerce-blocks”,后跟“woocommerce-blocks”
- 对函数和命令行操作的引用应以“内联代码”格式进行格式化。
示例:“使用
dig命令获取 DNS 信息。” - 函数应使用“内联代码”格式进行样式设置,并保留其原始来源确定的大小写格式。
示例:
WP_Query(而不是WP_query)
视觉辅助
视觉辅助工具,例如屏幕截图、图表、代码片段和视频,对于操作指南非常有用。 它们提供了一种视觉参考,可以帮助用户更轻松地理解说明。 在包含视觉辅助工具时,请务必清楚地对其进行标记,并提供标题或描述,以解释正在显示的内容。
缩写
可以使用更常以缩写形式出现的短语。 首次在任何 页面 上出现缩写时,必须包含完整的短语,后跟括号中的缩写。
示例:我们通过引入高性能订单存储 (HPOS) 增强了 WooCommerce 的查询功能。
之后,可以在整个 页面 中使用缩写。
在决定一个术语是否常用时,请考虑其对 翻译 和未来国际化 (i18n) 工作的潜在影响。
模式
文章内容
在创建操作指南时,重要的是使用一致且易于遵循的格式。 以下是一个软件操作指南的建议模板:
简介: 概述指南所涵盖的任务或功能。
前置条件: 列出完成任务或使用功能所需的任何 前置条件。
分步说明: 提供完成任务或使用功能的详细、分步说明。 使用编号的步骤,并在适当的情况下包含屏幕截图或其他视觉辅助工具。
故障排除: 包含一个 故障排除 部分,以解决用户可能遇到的常见问题或 错误。
结论: 总结指南中的关键点,并提供任何可能有所帮助的附加 资源 或参考资料。
术语表
组件和功能参考
- 首次在文章中出现时,应完整呈现 "WordPress 管理员仪表盘",之后用缩写形式 ("WP Admin")。 之后,可以在同一篇文章中,对于任何对 WordPress 管理员仪表盘的引用,都可以使用缩写形式。
- 引用 WordPress 管理员仪表盘的 URL 时,可以使用缩写形式
wp-admin。
测试
在发布教程或指南之前,重要的是对其进行彻底的测试,以确保说明准确且易于理解。
结构
拆分文档
如果文章涵盖了太多主题,可能会让用户难以找到他们想要的信息。"拆分文档" 指的是将内容过多的文章分解为一组较小的相关文章。 这组文章通常有一个主 "仪表盘",提供对该组文章的概述,描述性文本提供指向相关文章的链接,这些文章对用户来说可能很有用。 这些文章组可以被视为由较小、拆分的文章组成的 "信息" 单元。
将较小的内容块拆分为独立的文章,可以更容易地链接到特定主题,而不是依赖于链接到更广泛的文章,这些文章可能包含锚点。 这种更具体的链接方法对我们的支持团队很有帮助,但对于在整个文档站点上交叉链接文章也很有用。
贡献技术文档
感谢您帮助改进 WooCommerce 的开发者文档。 我们的文档由 Docusaurus 提供支持,位于 monorepo 中的 woocommerce/docs/ 文件夹中。
本指南将引导您了解贡献的结构、工具和流程。
快速开始
本指南假设您熟悉基本的 Git 和 GitHub 功能,并且您已登录到 GitHub 帐户,并且已在本地配置了 Git。 如果您是 GitHub 的新手,我们建议您在开始之前阅读他们的 快速入门 和 使用分支 指南。
初始设置
- 在 GitHub 上 fork WooCommerce monorepo。 如果提示,您可以安全地选中
copy the trunk branch only选项。 - 克隆您刚刚创建的分支。 这将允许您在本地进行编辑。
进行更改
-
在进行任何更改之前,请确保您的
trunk分支与 monorepo 的trunk同步。 -
对于您想要进行的每项修改,请在您的 fork 中,从
trunk创建一个以docs/开头的新的分支。 例如,如果您要添加一个关于改进扩展性能的文档,您可以将分支命名为docs/improve-extension-performance。 -
在
docs/下的适当文件夹中创建或编辑 Markdown 文件。 -
如果需要,请更新文件夹中的
_category_.json文件(用于侧边栏标签/位置)。 -
运行构建以验证更改,确认站点地图和 llms-txt 文件已更新,并检测 Markdown 语法错误和断开的链接(链接检查仅在构建时进行):
npm run build
打开拉取请求
- 提交并推送到您的 fork。
- 打开一个拉取请求 到 woocommerce/woocommerce,目标分支为
trunk。 - 使用描述性的标题,并填写 PR 模板。 包含:
- 新文件或分类的理由
- 关于任何侧边栏或结构更改的说明
- WooCommerce 开发者倡导团队将审查并合并您的更改。
文档文件夹结构
工具和配置
- 支持工具和配置 位于:
- 顶层侧边栏和导航栏 的配置位于:
文档文件
-
文档位置: 所有文档都位于
woocommerce/docs/目录下。 -
每个文件夹代表一个侧边栏或顶层导航的分类,例如:
getting-started、code-snippets等。 -
每个分类的侧边栏配置 使用每个分类文件夹内的
_category_.json文件进行管理:{ "position": 7, "label": "Code snippets" }
添加图像
所有文档图像都存储在:
docs/_docu-tools/static/img/doc_images/
要在 Markdown 文件中包含图像,请按以下方式引用它:

创建新的分类
在创建新的分类之前,您应该考虑是否真的有必要这样做。 尽可能地,应该将内容创建在现有的分类中。 如果确实需要创建新的分类,请按照以下步骤操作:
-
在
/docs文件夹中,创建一个具有描述性名称的子文件夹。 例如,如果您想创建一个Checkout design guidelines部分,则创建一个名为/docs/checkout-design-guidelines的文件夹。 -
在每个分类文件夹中创建一个
_category_.json文件,并指定其在侧边栏中的位置以及标签:{ "position": 10, "label": "Checkout design guidelines" }
在创建新的分类时,请在您的拉取请求的描述中包含创建该分类的理由。
撰写指南和参考
- 使用短的、适合 URL 的文件名(kebab-case,不包含空格)。
- 避免从富文本编辑器(如 Google Docs)粘贴内容,因为这可能会引入无效的字符。
- 请参考我们的 文档风格指南,以获取详细的撰写指南。
- 请参考 Docusaurus 文档,以获取更多指导。
WooCommerce 的代码回溯
代码回溯是指将 trunk 中的更改应用到发布分支的过程。 这确保了关键的修复程序能够通过即将发布的版本到达客户。 请注意,这些流程仅适用于即将发布的版本(而不是已经发布的版本的补丁)。
发布分支的生命周期
当创建发布分支时,它会在特性冻结时从 trunk 复制。 创建后:
- 发布分支不再接收新的特性更新
- 仅允许进行关键的更改
- 由于我们不会将发布分支合并回
trunk,因此发布分支中的任何修复程序也必须应用到trunk。
满足代码回溯条件的更改
只有满足以下条件的更改才能进行代码回溯:
- Bug 修复,影响发布
- 性能改进,影响 WooCommerce 的功能
- 时间敏感的功能,影响业务目标
- 合同上要求的特性,用于 WooCommerce
贡献者的代码回溯流程
标准工作流程:从 trunk 到发布分支
何时使用: 大多数代码回溯场景
- 将
trunk设置为您的基础分支 - 添加与您的目标版本匹配的里程碑(例如,
9.8.0) - 获取 PR 并将其合并到
trunk - 自动工作流程会创建一个用于发布分支的 cherry-pick PR
- 原始的贡献者或合并者 审查并合并回溯 PR
注意: 对于临近发布截止日期的紧急修复,请直接联系发布负责人。
替代工作流程:从发布分支到 trunk
何时使用: 必须直接针对发布分支的紧急修复
- 将发布分支设置为您的基础分支
- 如果更改也应该应用到
trunk,请添加标签cherry pick to trunk - 获取 PR 并将其合并到发布分支
- 自动工作流程会创建一个用于
trunk的 forward-port PR - 尽快合并
trunkPR,以避免延迟
重要提示
- 更改必须满足代码回溯的条件
- 冻结的发布版本仅接受关键的 bug 修复
- 所有代码回溯都需要审查和测试
- 应该及时合并到
trunk的 forward-port,因为这些更改会跟踪与原始 PR 相同的里程碑。
构建和发布版本
:::important
虽然本指南可作为参考,但请记住,特定于版本的说明已在 版本跟踪问题 中提供,这些问题是在发布周期之前创建的,并且应优先使用。
:::
本页面概述了从发布分支构建任何 WooCommerce 版本的必要步骤。请查看流程图以了解整体过程和决策表。以下提供了分步说明。
概述

指令
按照以下步骤的顺序执行。在运行任何 GitHub 工作流程时,请确保从 trunk 分支(默认分支)进行操作,并输入指定的版本或分支。
请随时准备好 发布故障排除与恢复 指南,以防遇到任何问题。
步骤
1. 预构建检查
- 确认 GitHub 服务 正在运行。
- 验证 发布里程碑 上是否存在任何未解决的问题或拉取请求。如有必要,请通知作者合并或关闭。
- 确保不存在任何 带有 "cherry pick failed" 标签 的拉取请求,这些拉取请求适用于此版本,并且尚未采取任何操作。
- 确认发布分支中
readme.txt文件的Stable tag值与 WordPress.org 的trunk中的值相匹配。
2. 构建发布包
- 运行工作流 Release: Bump version number: 输入发布主版本 (
x.y) 作为 Release branch,并从下拉菜单中选择发布类型。 - 审查并合并针对发布分支生成的 PR。
- 运行工作流 Release: Compile changelog: 输入发布主版本 (
x.y) 作为 Version,并保持 Release date 为空,除非是提前构建发布包。 - 审查并合并生成的 PR:一个针对
trunk,另一个针对发布分支。两者都应在发布里程碑下。 - 运行工作流 Release: Build ZIP file 以构建资源并创建 GitHub 发布:输入发布主版本 (
x.y) 作为 Release branch,并选中 Create GitHub release。 - 确认已在仓库中创建了草稿发布,并附带了
woocommerce.zip资源 在仓库中。
3. 将发布包上传到 WordPress.org
- 运行工作流 Release: Upload release to WordPress.org: 输入发布版本 (
x.y.z) 作为 Release tag to upload,并确保选中确认复选框。 - 确认 SVN 标签 存在于 WordPress.org SVN。
- 使用存储在密钥库中的
WordPress.org "WooCommerce" 用户帐户凭据,登录到 WordPress.org 并批准发布。 - 几分钟后,确认发布包 可供下载。
4. 部署到测试环境
:::caution
此步骤仅适用于 rc 或稳定版本 (x.y.0 及更高版本)。
:::
- 按照 部署到测试环境的指南 进行操作,并在部署后监控 4 小时(RC)或 2 小时(稳定版本)。
- 在发布 Slack 频道中创建一个线程,用于监控和讨论此发布。
如果在监控期间检测到严重问题
- 请求在测试环境中回滚。
- 暂停发布过程,并且 不要继续执行与此问题相关的任何步骤。请遵循 故障排除指南 中的步骤。
5. 发表发布版本
- (仅适用于稳定版本) 运行工作流程 Release: Update stable tag:输入发布版本 (
x.y.z) 作为 Version,并确保勾选 确认 复选框。 - 发表之前创建的 发布草稿,以及可能存在的其他来自先前尝试的发布草稿。确保 仅在稳定版本中勾选 "设置为最新发布"。
6. 发布后的任务
:::caution
此步骤仅适用于稳定版本 (x.y.0 及更高版本)。
:::
WooCommerce 发布监控
在发布后,发布负责人应继续监控以下内容,以查找与最新版本直接相关的任何错误。 监控应在主要发布后的 3 天内和点发布后的 1 天内继续。
如果存在疑问,即某个特定问题是否足够严重,以至于需要创建新的点发布修复,请在 WooCommerce Slack 上的 #core-development 频道发起讨论。
WordPress.org 论坛
检查 WordPress.org 论坛 上新创建的帖子,以查找任何似乎是由最新更新引起的 issue。
WooCommerce GitHub 仓库的 issue
查看 最新创建的 issue,并验证是否没有 critical 的 issue。
处理 critical 的 issue:点发布请求
如果监控发现了一个错误,并且该错误无法等待 下一次计划的发布,则应发起 点发布请求 (PRR)。 PRR 工作流程允许发布负责人加快修复程序,将其快速集成到当前的维护分支中,并在必要时,自动将其 cherry-pick 到 trunk 和下一个 frozen 分支。
在打开 PRR 之前,请确认该 issue:
- 影响核心商店功能(例如,结账、订单、税费)。
- 影响大量网站,或者源于广泛使用的扩展或主题。
- 缺乏合理的 workaround,即商家可以自行应用的方法。
如果满足这些条件,请按照 PRR 指南创建请求,提供必要的理由,并通知发布负责人进行批准和合并。
JavaScript 包的发布
WooCommerce 单仓库项目包含许多 JavaScript 组件,用于支持 WooCommerce 的开发,例如 @woocommerce/components,这些组件通过 NPM 进行分发。此发布流程由 GitHub Actions 进行管理。
有关如何发布 JavaScript 包的完整文档,请参阅 包发布工具文档。
WooCommerce 的小版本发布请求
小版本发布用于解决已发布 WooCommerce 版本中发现的严重问题。 这些是补丁版本(例如,9.9.0 → 9.9.1),仅包含生产环境中的必要修复。
请注意,此过程仅适用于已发布且在客户生产环境中的版本。
小版本发布生命周期
小版本发布与常规版本具有不同的生命周期:
- 由发布后发现的严重问题触发
- 范围有限 - 仅包含关键的错误修复和安全补丁
- 加速的时间线 - 更快的审查和发布周期
- 向后兼容性 - 不允许有破坏性更改
适用于小版本发布的变更
只有满足以下条件的变更才能用于小版本发布:
- 关键的错误修复,会导致数据丢失、安全漏洞或主要功能失效
- 安全补丁,用于解决已识别的漏洞
- 性能修复,用于解决严重的性能问题
- 合规性修复,用于满足法规或法律要求
以下内容不适用于小版本发布:
- 新功能或增强功能
- 非关键的错误修复
- 代码重构或清理
- 文档更新
小版本发布请求流程
标准流程:关键错误修复
何时使用: 大多数小版本发布场景
-
创建拉取请求,针对相应的发布分支(例如,
release/9.9用于修复 9.9.x 版本的错误) -
创建小版本发布请求 issue,使用 小版本发布模板 在主仓库中
-
在 issue 中提供详细的理由,包括:
- 影响评估(有多少客户受到影响)
- 业务影响(收入、合规性、安全隐患)
- 针对所提修复方案的风险评估
- 证据和重现步骤
-
等待发布负责人批准 - 发布负责人将批准该请求,这会自动为您的拉取请求添加 cherry-pick 标签
-
调整分支目标,通过修改自动添加的标签,以指定哪些其他分支需要该修复:
- 如果修复应该应用到主分支,请保留
cherry pick to trunk - 如果修复应该应用到当前的冻结版本,请保留
cherry pick to frozen release - 移除不需要修复的分支的标签
- 如果修复应该应用到主分支,请保留
-
让您的拉取请求经过审查、测试并合并 到目标发布分支
-
自动化系统会创建 cherry-pick 拉取请求,根据仍然应用于您的原始拉取请求的标签,将修复应用到其他分支
-
尽快审查和合并 cherry-pick 拉取请求,以确保它们不会延误下一次发布。 这些 cherry-pick 拉取请求将使用与原始关键修复相同的里程碑,并且必须在小版本发布之前合并。
补丁版本
什么是补丁版本?
补丁版本是针对特定问题而发布的,不包含大量新功能的修复版本。补丁版本通常包含:
- 关键的错误修复,影响商店功能或结账流程。
- 安全补丁,用于解决紧急漏洞。
- 兼容性修复,用于解决 WordPress、主题或插件冲突。
确定补丁版本的发布时间
在确定发布补丁版本的最佳时间时,请根据未解决问题的紧迫性和严重程度,运用您的最佳判断:
- 如果问题不太紧急,请考虑等待 3-4 天,看看是否会报告其他相关问题,然后再继续。这有助于整合修复,并减少补丁版本的数量。
- 对于高危或关键问题,应优先尽快发布,以最大限度地减少对用户的潜在影响。
- 对于安全问题,请与实施安全修复的团队协调,以帮助确定紧迫性,如果情况尚不清楚。
- 考虑是否已经有其他已知问题正在处理,这些问题可以包含在同一版本中。
补丁版本请求 (PRR) 流程
补丁版本请求 (PRR) 流程 是一个结构化的过程,用于请求和管理需要包含在 WooCommerce 补丁版本中的关键修复。 此过程可确保紧急错误修复可以安全地合并到当前的稳定版本中,并自动将其移植到主分支和任何冻结分支,从而保持代码质量,强制进行彻底的审查,并防止出现回归。
⚠️ 重要: 安全漏洞报告不应通过 PRR 流程。 所有潜在的安全问题应通过 Automattic 的 HackerOne 计划私下报告:https://hackerone.com/automattic/。
步骤流程
1a. 初始问题创建
为了确保发布负责人了解所有计划包含在下一个补丁版本中的修复,当发现一个错误并计划将其作为修复时,重要的是立即创建问题或 PR。 这将有助于减少需要创建的补丁版本的数量。
如果初始 PR 的创建可能需要几个小时以上,请创建一个问题,并将问题的里程碑设置为目标版本。 例如,对于 10.1.x 的新补丁版本请求,请使用里程碑 10.1.0。
1b. 初始拉取请求创建
作者操作: 创建一个拉取请求,针对发布分支 (release/x.y),而不是主分支,并遵循标准的 PR 创建流程。
- PR 应该针对特定的发布分支(例如,对于 WooCommerce 9.5.x 中发现的问题,请使用
release/9.5)。 - 包含一个常规的变更日志文件,就像为主分支的 PR 所做的那样。
- 确保满足所有标准 PR 要求(描述、测试等)。
- 确保 PR 设置了目标版本的里程碑,以便发布负责人可以跟踪它,例如,对于
10.1.x的新补丁版本请求,请使用里程碑10.1.0。
2. 细分版本请求提交
作者操作: 使用 细分版本请求模板 提交细分版本请求 (PRR)。
提供所需的细分版本请求模板信息:
必填字段:
- PR URL: 针对发布分支的拉取请求 URL
- Justification: 为什么需要此细分版本
- Impact Assessment: 如果不包含此修复,可能造成的后果(受影响的用户数量以及影响方式)
- Contingency Plan: 如果在细分版本发布后发现缺陷,应该怎么办
- Communication Plan: 如何在发布博客文章中宣传此更改
- Workaround: 任何可用的临时解决方案以及如何告知用户
- Alternative Contact: 如果作者不可用,应该联系谁
3. 发布负责人审核
当提交了细分版本请求后,发布负责人会进行评估。 在决定是否批准细分版本请求时,发布负责人应考虑以下因素:
| 评估标准 | 指导 |
|---|---|
| 影响范围 | 已经有多少商店受到影响? 影响范围越大,紧急程度越高。 |
| 错误常见性 | 该问题是否源于广泛使用的核心功能、插件或主题? 常见组件中的问题通常需要更快的处理。 |
| Workarounds | 是否存在简单的、经过文档记录的临时解决方案(例如,过滤器、设置切换或临时功能禁用),商店所有者可以应用? 容易获得的临时解决方案会降低对细分版本的需求。 |
| 影响严重性 | 该错误是否会阻止关键的商业功能(结账、支付、产品可见性)? 商业功能失败越关键,优先级越高。 |
4. 批准或拒绝
| 结果 | 发布负责人操作 | 触发的工作流 |
|---|---|---|
| 批准 | 为细分版本请求问题添加 Approved 标签,并可以选择留下简短的理由,引用上述标准。 |
工作流会自动为 PR 添加标签(“cherry pick to trunk”,“cherry pick to frozen release”);将问题的里程碑设置为当前发布版本;在细分版本请求中添加批准说明。 |
| 拒绝 | 添加 Rejected 标签,并简要说明原因(例如,影响范围有限,有简单的临时解决方案可用)。 |
工作流会添加一条评论,关闭细分版本请求,作者必须将 PR 重新定向到 trunk 分支,解决冲突,并通过正常的流程合并。 |
5. 合并到发布分支 (发布负责人 / 核心贡献者)
-
验证 cherry-pick 要求
- 检查该修复是否已包含在
trunk和/或下一个冻结分支中。 - 如果该修复不应该被移植到未来版本,移除
cherry pick to trunk和cherry pick to frozen release标签。
- 检查该修复是否已包含在
-
合并 PR
- 在审查标签后,将 PR 合并到当前的
release/x.y分支。 - 确认变更日志条目和里程碑是否正确。
- 在审查标签后,将 PR 合并到当前的
-
结果自动化
- 如果任一 cherry-pick 标签仍然存在,GitHub Actions 会打开后续 PR,目标是
trunk和/或冻结的发布分支。 - 如果两个标签都被移除,则不会运行任何 cherry-pick 工作流。
- 如果任一 cherry-pick 标签仍然存在,GitHub Actions 会打开后续 PR,目标是
6. 审查和合并后续 PR (发布负责人)
在主修复合并到 release/x.y 后,PR 上剩余的标签将决定下一步的操作:
| 标签存在 | 自动化结果 | 发布负责人必须做什么 |
|---|---|---|
cherry pick to trunk |
Action 打开一个新的 PR,目标是 trunk,并添加当前的里程碑。 |
审查测试 / CI,并合并此 PR。 |
cherry pick to frozen release |
Action 打开一个新的 PR,目标是 下一个冻结分支(例如,release/9.6),并添加里程碑。 |
审查并合并此 PR。 |
这两个后续 PR 必须在创建 point-release 标签之前合并。 如果不需要任何 cherry-pick,请确保在步骤 5 中移除了相应的标签,以避免生成不必要的 PR。
7. 发布 point release (发布负责人)
一旦所有必需的 PR 都已合并到:
release/x.y(当前维护分支)trunk(未来的特性分支)- 可选 冻结分支 (
release/x.y+1)
发布负责人 创建并发布新的 point release,其中包含自上次发布以来所有已批准的 PRR。
请遵循已建立的 WooCommerce 发布流程。
WooCommerce 预发布版本
WooCommerce 预发布版本提供对即将推出的功能和改进的早期访问,允许开发者、测试人员和社区为未来的发布做好准备。
本文档概述了可用的不同类型的预发布版本、它们的发布时间以及它们在整体发布周期中的位置。
| 发布名称 | 预计发布时间 |
|---|---|
nightly |
每天晚上 |
-dev |
在功能冻结时 |
-beta.1 |
功能冻结后 1 周 |
-beta.2, ... |
至少再发布 1 个,根据需要,在 -rc.1 之前 |
-rc.1 |
在最终发布前不久(约 1 天) |
Nightly 版本
Nightly 版本每天基于 trunk 的当前内容重新生成。可以在 GitHub 上的 nightly 标签下找到。
这些版本仅在 GitHub 仓库中可用,并且不会公开宣布或上传到 WordPress.org。
发布周期预发布版本
当即将发布的版本(X.Y.0)的功能冻结时,会创建一个特定于发布的分支(命名为 release/x.y),该分支用于稳定、修复回归并构建与该发布周期相关的预发布版本。
这些版本会在不同的时间点进行标记,具体如下。 像往常一样,任何特定日期的权威信息来源是 我们的发布日历。
-dev 版本
这是一个自动生成的标签,在当前周期的功能冻结时创建。 例如,当 10.1.0 的功能冻结时,创建了 10.1.0-dev 标签。
这是一个内部开发标签,仅在 GitHub 仓库中可用,不在 WordPress.org 上可用。
Beta 版本
旨在供插件作者和早期采用者使用,以测试即将发布的版本的功能和功能。 第一个 Beta 版本通常在功能冻结后 1 周发布。
Beta 版本会逐步进行版本控制,从 -beta.1 开始,然后是 -beta.2,依此类推。
我们旨在每个周期发布至少 2 个 Beta 版本,但如果任何重要的错误修复或功能需要额外的测试或在最终稳定版本之前收到重要的更新,则可能会发布更多 Beta 版本。
所有 Beta 版本都可以在 GitHub 和 WordPress.org 上使用。
有关如何参与 WooCommerce Beta 测试并提供有价值的反馈的指南,请参阅我们的 Beta 测试文档。
候选发布版本 (RC)
这些是预发布版本,它们的功能已经全部实现,并且被认为足够稳定,可以进行最终测试。 RC 通常在最终发布之前不久发布,并在内部用于进行最终的测试和检查。
它们的版本号会逐步递增,例如 -rc.1、-rc.2,以此类推。
我们的目标是在最终发布之前发布至少一个 RC 版本。该版本不会公开宣布,但会在 GitHub 和 WordPress.org 上进行标记,并且可以下载。
WooCommerce 发布计划
WooCommerce 遵循可预测的发布计划,大约每五周发布一次更新,其中包含新功能、增强功能和错误修复。 本页面总结了我们发布过程的主要阶段,例如功能冻结、beta 和候选版本阶段,以及最终版本和补丁版本的发布时间。
有关 monorepo 内部发布周期详情,请访问我们的 Git Flow 文档。
:::tip
要查看当前和即将发布的实际计划,请访问我们的 发布日历。
:::

里程碑
功能冻结 & -dev 版本 (第 1 天)
由于功能冻结自动化,会发生以下几件事:
- 创建一个专用的发布分支 (
release/x.y),未来的版本将在该分支上进行测试和稳定。 此分支不包含任何新功能,仅包含错误修复。 - 构建一个
-dev版本,并在 GitHub 上提供。 - 新功能的开发继续在
trunk上进行。 - 在我们的开发者网站上发布一个预发布公告 (示例)。
Beta 1 (+1 周)
在此阶段,进行各种测试过程:
- (内部) 使用 Woo 维护的扩展进行回归测试,在多个环境中进行回归测试,以及进行探索性测试(包括由贡献团队进行)。
- (社区) 发布预版本,以便社区可以 开始测试。
在 beta 阶段发现的任何问题,要么直接针对发布分支进行修复,要么通过从 trunk 移植修复程序(首选)。 请参阅 移植指南 了解更多详情。
release/x.y 是即将发布的版本的唯一参考。
Beta 2 (+1 周)
在此阶段,我们将 -beta.1 中发现的回归修复作为发布稳定的一部分发布。 预发布公告将继续更新。
RC 1 (+1 周)
在最终发布之前,进行最后一次(内部)检查。
如果在此阶段发现任何问题,则将修复程序合并到发布分支 (release/x.y),就像在 beta 阶段一样。
最终版本 (+1 天)
我们将稳定的版本提供给所有人。 此时,开发者宣传团队将发布预先准备好的发布亮点 (示例)。
Point/Patch 发布
补丁发布用于向我们的用户提供重要的 bug 修复,这些 bug 是在最终发布后检测到的。 它们的版本号为 x.y.z,其中 z 不为零。
我们在合并任何修复时,遵循与 beta 和 RC 阶段相同的约定:
- 仅在发布分支中存在的 bug,将针对发布分支
release/x.y进行修复。 - 在
trunk上有可用修复的 bug,将进行 回移植。
延迟
由于业务需求或在测试过程中发现的任何关键 bug,发布日期可能会发生变化。
我们不会轻易做出这个决定,仅是为了确保发布的稳定性。 当这种情况发生时,我们始终会沟通情况(示例)并更新发布日历。
有关如何管理延迟的详细信息,请参阅 发布故障排除指南。
发布故障排除与恢复
本网页提供了在 WooCommerce 发布过程中可能出现问题的故障排除和恢复指南。它涵盖了常见场景、推荐操作以及最佳实践,以帮助确保发布过程顺利进行,并高效地解决任何问题。
场景 / 常见问题解答
构建发布时,工作流程失败
- 打开 GitHub 中工作流程运行的详情(在 Actions 选项卡下),以查看确切的失败位置和原因。 通常,工作流程会显示清晰的错误信息。
- 仔细阅读错误信息。 有时,问题可能只是由于缺少工作流程配置或跳过某个步骤。
- 如果您不确定错误意味着什么或如何继续, 请随时在发布 Slack 频道寻求帮助。 获得第二意见总比猜测要好。
⚠️ 在您了解失败的原因之前,请勿重新运行任何工作流程。 重新运行而不修复根本问题可能会使情况更加复杂。
与发布相关的 PR 上,CI 测试失败
在发布过程中,您可能会遇到与发布相关的 PR 上的 CI 测试失败。 这些失败有时是由于测试修复已合并到主分支,但在创建发布分支之前未回溯到该分支。
- 识别原因: 检查失败的测试是否在主分支上通过。 如果通过,则可能需要将修复回溯到发布分支。
- 回溯测试修复: 如果可能,回溯来自主分支的相关测试修复到发布分支,然后重新运行 CI 工作流程。
- 处理复杂情况: 如果由于依赖关系或其他原因无法回溯,请记录您发现的内容,并在发布 Slack 频道寻求帮助。 "Heart of Gold - Flux" 团队可以协助解决阻止发布工作的 CI 问题。
最终发布的 ZIP 文件出现问题,我可以重新开始吗? {#can-i-start-over-id}
如果在下载并解压生成的制品后,发现出现问题(例如,缺少文件、变更日志不正确或版本不匹配),这通常意味着:
- 某个必需的工作流程未运行或失败(例如,跳过了变更日志步骤)。
- 来自工作流程的自动生成的 PR 在构建 ZIP 文件之前未合并到发布分支。
在尝试重新构建版本之前:
- 删除任何与错误版本相关的 GitHub 草稿版本或标签:
- 转到 代码 > 版本 并删除草稿版本。
- 在 代码 > 标签 中,删除与错误版本的标签。如果跳过此步骤,最终版本可能会指向历史记录中的错误提交。
- 检查
release/X.Y分支的状态(可以在 GitHub UI 中或在本地拉取最新更改后进行检查)。 - 找出哪个步骤失败。例如,如果插件头版本正确但缺少变更日志,则只需重新运行变更日志步骤。
- 审查任何 自动生成的 PR:如果存在未合并且不再需要的打开的 PR,请关闭它们并删除其分支。
一旦您知道哪个步骤失败, 仅重新运行该步骤,具体方法请参阅 构建和发布指南。 确保以正确的顺序运行跳过的流程,并在继续之前仔细检查所有配置(版本号、发布类型等)。
在内部检查/监控期间检测到严重错误 {#deploy-serious-bug}
对于 RC 和稳定版本,在公开发布之前,必须将版本部署到我们的测试环境并进行错误监控。 如果在监控期间检测到严重错误,请执行以下步骤:
- 请求回滚 测试环境中的部署。
- 立即暂停发布过程,并且不要继续执行跟踪问题中剩余的任何步骤。
- 更新跟踪问题,说明发布已阻止,并包含有关错误的详细信息。
- 不要发布 任何已创建的 GitHub 草稿版本,但也不要删除 它们。 稍后将与通过验证的版本一起发布它们。
- 与相关的工程团队 协调,以开发修复程序。
- 如果需要调整或公开沟通发布计划,请联系开发者支持团队 (有关延迟的更多信息,请参阅下文)。
错误修复合并到发布分支后,如何操作?
- 创建新的跟踪问题,用于新的版本(例如,如果错误是在
-rc.1版本中检测到的,则为-rc.2;如果是在监控x.y.1版本时检测到的,则为x.y.2),通过运行Release: Create Tracking Issue工作流。不要重复使用现有的跟踪问题。 - 按照正常的发布流程,处理新的版本。
- 发布所有受影响版本的草稿版本。即使之前的版本没有公开可用,也必须将其发布,并且每个版本都将有自己的变更日志部分。
在 WordPress.org 上标记为稳定的版本中出现了一个严重错误。
如果发现严重的回归或错误(例如,结账失败或无法恢复的数据丢失):
- 立即通知相关的工程团队。
- 准备进行一个 Point Release。
- 暂时将 WordPress.org 上的稳定标签回退到之前的已知良好版本:
- 确定正确的先前版本,并记录其确切版本号。
- 使用
Release: Update stable tag工作流,确保选中 Revert 选项,以允许降级。 - 立即合并任何自动生成的 PR。
发布需要延迟。我们应该怎么办? {#release-delay}
- 创建一个内部 Slack 频道,以便与工程团队以及 Dev Advocacy 团队进行沟通。这还为团队提供了一个机会,可以分享任何额外的上下文,并验证或质疑时间表变更。
- 安排 Dev Advocacy 团队公开宣布延迟。
- 如果对包含修复的补丁版本有明确的预计发布时间 (ETA),请 更新发布日历,添加新的日期。
请记住,不要计划补丁版本的发布 过于接近周末。
发布已延迟。我们是否可以在周二之后仍然发布? {#release-delay-weekend-id}
一般来说,应避免在周二之后发布,尤其是在接近周末的时候。
即使补丁已经准备好并且似乎解决了问题,也很难确定是否没有其他隐藏的问题,并且在周末晚些时候发布可能会导致大多数团队成员无法监控或响应问题。
一般来说,如果犹豫不决,最好推迟一周的发布,以确保万无一失。
发布流程
WooCommerce 的发布流程由一系列 GitHub Actions 工作流支持,这些工作流可以自动化重复性任务、强制执行流程规范,并发送通知。本网页提供了所有与发布相关的流程的参考,并按触发方式进行组织。
所有工作流都定义在 .github/workflows/ 目录中。
计划任务
这些工作流每天自动运行。
| 工作流 | 计划 | 执行内容 | 执行时机 |
|---|---|---|---|
| Release: 作业 | 每天 18:00 UTC | 检查 发布日历,分配发布负责人,并为每个周期中的每个发布创建父级跟踪问题,以及每个子问题的子问题。为每个子问题调用 Create Tracking Issue。 | 在特性冻结前 ~8 周。 |
| Release: 强制特性冻结 | 每天 18:00 UTC | 检查 发布日历,从 trunk 创建发布分支,将 trunk 更新到下一个开发版本,发布一个开发版本,清理旧的里程碑,并发送 Slack 通知。调用 Bump version number 和 Build ZIP file。 |
在特性冻结日期。 |
| Release: 特性亮点通知 | 每天 09:00 UTC | 检查 发布日历,并向团队发送 Slack 提醒,告知即将到来的特性冻结截止日期。 | 在特性冻结前 ~1 周。 |
| Release: 打开问题警告 | 每天 18:00 UTC | 检查 发布日历,查找发布里程碑中未关闭的项目,并通过 Slack 通知列出这些项目及其负责人。 | 在发布日期前 72 小时内。 |
| Nightly builds | 每天 00:00 UTC | 从 trunk 构建一个夜间 ZIP 文件,并将其上传到 GitHub 发布版本。 每天运行,与发布日历无关。 |
每天。 |
事件驱动的工作流
这些工作流由 GitHub 事件自动触发,例如拉取请求合并、发布版本或标记问题。
代码选取和回溯
| 工作流程 | 触发器 | 功能描述 |
|---|---|---|
| 将里程碑 PR 代码选取到发布分支 | PR 关闭或在 trunk 上标记里程碑 |
从 trunk 中选取代码,并将其应用到 release/x.y 分支,匹配 PR 的里程碑。 使用 shared-cherry-pick 实现核心逻辑。 |
| 代码选取到冻结的发布版本 | PR 在 release/x.y 分支上合并,并且带有 cherry pick to frozen release 标签 |
从 release/x.y 分支选取代码,并将其应用到下一个(冻结的)release/x.y 分支。 使用 shared-cherry-pick 实现核心逻辑。 |
| 代码选取到主干 | PR 在 release/x.y 分支上合并,并且带有 cherry pick to trunk 标签 |
从 release/x.y 分支选取代码,并将其回溯到 trunk。 使用 shared-cherry-pick 实现核心逻辑。 |
| 如果存在代码选取冲突,则阻止合并 | cherry-pick-* 分支上的 PR 事件 |
如果存在 cherry pick has conflicts 标签,则 CI 构建失败,防止 PR 在冲突解决和标签移除之前被合并。 |
里程碑管理
| 工作流程 | 触发器 | 功能描述 |
|---|---|---|
| 自动为发布 PR 添加里程碑 | PR 打开或重新打开在 release/x.y 分支上 |
为目标 release 分支的 PR 自动分配相应的里程碑。 |
| 合并时自动分配里程碑 | PR 在 trunk 上关闭 |
为合并到 trunk 且尚未分配里程碑的 PR 分配里程碑。 |
发布事件和验证
| 工作流程 | 触发器 | 功能 |
|---|---|---|
| Release: Release events proxy | 已发布或预发布版本 | 委托给 release-new-release-published 以执行发布后的操作:发送 Slack 通知,更新全局变更日志(针对稳定版本),并为 beta 版本调用 Generate Number of Commits and Contributors。 |
| Release checks run | 已发布或编辑的版本 | 对已发布的版本运行 CI 测试套件。 此外,还会在预定时间 nightly 运行。 |
带有 code freeze exception、point release request、Approved 或 Rejected 标签的问题 |
手动工作流程
这些工作流程由发布负责人在发布过程中触发。 它们是 构建和发布指南 和发布跟踪问题中引用的工作流程。
构建和发布
| 工作流程 | 功能 |
|---|---|
| Release: Bump version number | 更新插件文件中版本号,并针对发布分支创建 PR。 |
| Release: Compile changelog | 编译变更日志条目,并针对 trunk 和发布分支创建 PR。 |
| Release: Build ZIP file | 构建发布 ZIP 文件,并可选地创建草稿 GitHub 发布版本。 |
| Release: Upload release to WordPress.org | 将发布 ZIP 文件上传到 WordPress.org SVN。 |
| Release: Update stable tag | 更新 WordPress.org 上的稳定标签,并创建 PR 以将其同步到仓库。 |
跟踪和分析
| 工作流程 | 功能描述 |
|---|---|
| Release: Create Tracking Issue | 为特定的版本创建 Linear 跟踪问题,使用 .linear/ 目录中的 模板。 |
| Release: Generate Number of Commits and Contributors | 生成 发布 统计信息(提交 数值、贡献者 列表)并 发送 Slack 通知。 |
| Release: analyze trends (CFEs and PRRs) | 创建 GitHub 问题,请求对 代码 冻结异常和点 发布 请求进行 AI 分析,用于一个里程碑。 |
JavaScript 包的发布
WooCommerce 单仓库项目包含许多 JavaScript 组件,用于支持 WooCommerce 的开发,例如 @woocommerce/components,这些组件通过 NPM 进行分发。此发布流程由 GitHub Actions 进行管理。
有关如何发布 JavaScript 包的完整文档,请参阅 包发布工具文档。
Beta 测试
Beta 测试对于确保我们的发布版本尽可能无 bug 至关重要,并且可以让我们在将更改正式发布之前收集用户反馈。 任何人都可以参与 Beta 测试,包括商店所有者、插件开发者、主题开发者、译者,我们欢迎任何形式的帮助。
我们理解,测试过程可能有些繁琐,因为您需要下载一个带有标签的版本,然后手动将其上传到您的测试站点。有时,这也会导致插件目录命名出现问题,因为带有标签的版本可能不会以 woocommerce 命名的目录。这可能会破坏扩展程序。
为了简化此过程,我们发布了一个 Beta 测试插件,以帮助安装 WooCommerce 的 Beta 版本,并确保目录名称正确。
请确保您负责任地进行测试,除非您有经验并且能够预见更改和故障,否则不建议在生产站点上运行 Beta 版本。
安装 Beta 测试插件
要开始,请转到“插件”>“添加新”>“上传插件”,然后安装 Beta 测试插件,您可以从以下地址下载:
此插件将让您访问所有上传到 [WordPress.org] 的 WooCommerce 版本。这包括 Beta 版本和 Release Candidate 版本。
提供反馈
在测试过程中,如果您发现任何 bug 或希望提出或贡献任何改进,请在 GitHub 上提交问题. 请务必阅读我们的贡献指南,并注明您正在使用的具体版本。 您还可以通过Beta 测试插件轻松地在 GitHub 上提交新的问题。
有时,我们可能会通过其他方式请求反馈,例如通过 开发者博客 上的调查问卷和测试邀请。 我们非常感谢您提供的即时反馈、评论和对调查问卷的回复,这有助于我们评估我们的发布版本和 Beta 版本的受欢迎程度,并帮助我们塑造未来的版本。
感谢您测试 WooCommerce!
WooCommerce 核心关键流程
我们已经确定了 WooCommerce 核心中我们认为最重要的用户流程。这些流程将帮助我们集中和优先安排我们的测试工作。它们还将帮助我们考虑更改的影响以及问题的优先级。
随着平台的不断发展,这些流程将不断演变,包括更新、添加或重新确定优先级。
购物者关键流程领域
商家关键流程领域
- 商家 > 入门
- 商家 > 仪表盘
- 商家 > 设置
- 商家 > 优惠券
- 商家 > 营销
- 商家 > 分析
- 商家 > 产品
- 商家 > 订单
- 商家 > 客户
- 商家 > 邮件
- 商家 > 插件
- 商家 > 我的订阅
- 商家 > 网页
- 商家 > 帖子
购物者 - 商店
| 用户类型 | 流程领域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 购物者 | 商店 | 搜索商店 | shopper/shop-search-browse-sort.spec.js |
| 购物者 | 商店 | 按分类浏览 | shopper/shop-search-browse-sort.spec.js |
| 购物者 | 商店 | 可以排序商品 | shopper/shop-search-browse-sort.spec.js |
| 购物者 | 商店 | 从商店页面将简单产品添加到购物车 | shopper/cart.spec.js |
| 购物者 | 商店 | 显示商店目录 | shopper/shop-search-browse-sort.spec.js |
| 购物者 | 商店 | 按标签显示产品 | shopper/product-tags-attributes.spec.js |
| 购物者 | 商店 | 按属性显示产品 | shopper/product-tags-attributes.spec.js |
| 购物者 | 商店 | 使用产品筛选器 | shopper/shop-products-filer-by-price.spec.js |
Shopper - 产品
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Shopper | 产品 | 将简单产品添加到购物车 | shopper/product-simple.spec.js |
| Shopper | 产品 | 将分组产品添加到购物车 | shopper/product-grouped.spec.js |
| Shopper | 产品 | 可变产品的详细信息会根据变体而更新 | shopper/product-variable.spec.js |
| Shopper | 产品 | 将可变产品添加到购物车 | shopper/product-variable.spec.js |
| Shopper | 产品 | 显示推荐产品 | products/product-linked-products.spec.js |
| Shopper | 产品 | 显示相关产品 | products/product-linked-products.spec.js |
| Shopper | 产品 | 显示评论 | merchant/product-reviews.spec.js |
| Shopper | 产品 | 添加评论 | merchant/product-reviews.spec.js |
| Shopper | 产品 | 查看产品图像 | shopper/product-simple.spec.js |
| Shopper | 产品 | 查看产品描述 | shopper/product-simple.spec.js |
产品描述
- 简单产品:
Simple Product - 可变产品:
Variable Product - 分组产品:
Grouped Product
操作
- 查看产品:
View Product - 添加组:
Add Group - 查看专业版:
View Pro - 显示:
Display - 添加到购物车:
Add to Cart - 添加评论:
Add review - 播放:
Play
页面元素
- 链接:
Link - 图像:
Images - 日期:
Date - 购物车:
Cart - 描述:
Descriptions - 评论:
Reviews
状态
- 待审:
Pending - 变体:
Variation
其他
- 产品:
Product - 相关产品:
Related products - 测试:
TEST
顾客 - 购物车
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 顾客 | 购物车 | 当启用时,"加入购物车" 重定向到购物车页面 | shopper/cart-redirection.spec.js |
| 顾客 | 购物车 | 查看购物车 | shopper/cart.spec.js |
| 顾客 | 购物车 | 在限制范围内更新产品数量 | shopper/cart.spec.js |
| 顾客 | 购物车 | 从购物车移除产品 | shopper/cart.spec.js |
| 顾客 | 购物车 | 应用所有类型的优惠券 | shopper/cart-coupons.spec.js |
| 顾客 | 购物车 | 根据地址显示配送选项 | shopper/calculate-shipping.spec.js |
| 顾客 | 购物车 | 查看空购物车 | shopper/cart.spec.js |
| 顾客 | 购物车 | 显示正确的税费 | shopper/cart-checkout-calculate-tax.spec.js |
| 顾客 | 购物车 | 遵守优惠券使用限制 | shopper/cart-checkout-coupons.spec.js |
| 顾客 | 购物车 | 显示交叉销售产品 | products/product-linked-products.spec.js |
| 顾客 | 购物车 | 继续结账 | shopper/checkout.spec.js |
顾客 - 结账
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 顾客 | 结账 | 订单详情页面显示正确的商品 | shopper/checkout.spec.js |
| 顾客 | 结账 | 可以添加配送地址 | shopper/checkout.spec.js |
| 顾客 | 结账 | 访客用户可以下单 | shopper/checkout.spec.js |
| 顾客 | 结账 | 创建账户 | shopper/checkout-create-account.spec.js |
| 顾客 | 结账 | 登录到现有账户 | shopper/checkout-login.spec.js |
| 顾客 | 结账 | 现有用户可以下单 | shopper/checkout.spec.js |
| 顾客 | 结账 | 使用所有类型的优惠券 | shopper/checkout-coupons.spec.js |
| 顾客 | 结账 | 查看结账页面 | shopper/checkout.spec.js |
| 顾客 | 结账 | 当表单不完整时显示警告 | shopper/checkout.spec.js |
| 顾客 | 结账 | 添加账单地址 | shopper/checkout.spec.js |
| 顾客 | 结账 | 遵守优惠券的使用限制 | shopper/cart-checkout-coupons.spec.js |
| 顾客 | 结账 | 在结账页面显示正确的税费 | shopper/cart-checkout-calculate-tax.spec.js |
| 顾客 | 结账 | 查看订单确认页面 | shopper/checkout.spec.js |
顾客 - 邮件
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 顾客 | 邮件 | 顾客账户邮件接收 | shopper/account-email-receiving.spec.js |
| 顾客 | 邮件 | 顾客订单详情邮件接收 | shopper/order-email-receiving.spec.js |
顾客 - 我的账户
| 用户类型 | 功能区域 | 功能名称 | 测试文件 |
|---|---|---|---|
| 顾客 | 我的账户 | 创建账户 | shopper/my-account-create-account.spec.js |
| 顾客 | 我的账户 | 登录现有账户 | shopper/my-account.spec.js |
| 顾客 | 我的账户 | 查看账户详情 | shopper/my-account.spec.js |
| 顾客 | 我的账户 | 更新地址 | shopper/my-account-addresses.spec.js |
| 顾客 | 我的账户 | 查看订单 | shopper/my-account-pay-order.spec.js |
| 顾客 | 我的账户 | 支付订单 | shopper/my-account-pay-order.spec.js |
| 顾客 | 我的账户 | 查看下载 | shopper/my-account-downloads.spec.js |
商家 - 入口
| 用户类型 | 功能区域 | 功能名称 | 测试文件 |
|---|---|---|---|
| 商家 | 核心个人资料 | 介绍与选择加入 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 用户个人资料信息 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 商家信息 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 扩展页面 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | WooPayments 包含在符合条件的扩展中 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | WooPayments 不包含在不符合条件的扩展中 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 安装所有默认扩展 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 完成站点设置 | activate-and-setup/core-profiler.spec.js |
| 商家 | 核心个人资料 | 跳过介绍并确认商家位置 | activate-and-setup/core-profiler.spec.js |
商家 - 仪表盘
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | WC 首页 | 完成个人资料设置后重定向到首页 | |
| 商家 | WC 首页 | 完成任务列表中的所有步骤 | |
| 商家 | WC 首页 | 隐藏任务列表 | |
| 商家 | WC 首页 | 在完成任务列表后显示店铺管理 | |
| 商家 | WC 首页 | 从统计概览直接访问分析报告 | |
| 商家 | WC 首页 | 在升级后保留任务列表完成状态 | |
| 商家 | WC 首页 | 与扩展的任务列表交互 | |
| 商家 | 活动面板 | 与活动按钮交互 | |
| 商家 | 消息中心 | 与便笺交互并执行操作 | |
| 商家 | 消息中心 | 隐藏单个便笺和所有便笺 |
商家 - 设置
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | 设置 | 更新常规设置 | merchant/settings-general.spec.js |
| 商家 | 设置 | 添加税率 | merchant/settings-tax.spec.js |
| 商家 | 设置 | 添加配送区域 | merchant/create-shipping-zones.spec.js |
| 商家 | 设置 | 添加配送类型 | merchant/create-shipping-classes.spec.js |
| 商家 | 设置 | 启用本地自提功能,用于结账流程 | merchant/settings-shipping.spec.js |
| 商家 | 设置 | 更新支付设置 | admin-tasks/payment.spec.js |
| 商家 | 设置 | 处理产品品牌 | merchant/create-product-brand.spec.js |
商家 - 优惠券
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | 优惠券 | 添加所有优惠券类型 | merchant/create-coupon.spec.js |
| 商家 | 优惠券 | 添加受限优惠券 | merchant/create-restricted-coupons.spec.js |
商家 - 营销
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | 营销 | 显示营销概览 | admin-marketing/overview.spec.js |
商户 - 数据分析
| 用户类型 | 功能区域 | 功能名称 | 测试文件 |
|---|---|---|---|
| 商户 | 数据分析 | 查看收入报告 | admin-analytics/analytics.spec.js |
| 商户 | 数据分析 | 查看概览报告 | admin-analytics/analytics-overview.spec.js |
| 商户 | 数据分析 | 确认概览报告中的摘要数字是否正确 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 在概览页面使用日期过滤器 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 自定义概览页面的性能指标 | admin-analytics/analytics-overview.spec.js |
| 商户 | 数据分析 | 在收入报告中使用日期过滤器 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 将收入报告下载为 CSV 格式 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 在订单报告中使用高级过滤器 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 数据分析设置 | admin-analytics/analytics-data.spec.js |
| 商户 | 数据分析 | 在收入报告中设置自定义日期范围 | admin-analytics/analytics-data.spec.js |
商家 - 产品
本页面展示了商家的产品列表。
产品管理
- 添加产品: 点击 "添加产品" 按钮,可以创建一个新的产品。
- 编辑产品: 点击产品列表中的 "编辑" 按钮,可以修改产品的详细信息。
- 删除产品: 点击产品列表中的 "删除" 按钮,可以删除产品。 删除操作不可逆。
- 批量操作: 支持批量上传和删除产品。
产品详情
每个产品包含以下信息:
- 产品名称: 产品的名称。
- 产品描述: 产品的详细描述。
- 产品图片: 产品的图片。
- 价格: 产品的价格。
- 库存: 产品的库存数量。
- 分类: 产品的分类。
- SKU: 产品的唯一标识符。
- 状态: 产品的状态(例如:已上架、已下架)。
产品状态管理
- 上架/下架: 可以对产品进行上架和下架操作,控制产品在商店的显示。
高级功能 (仅限 Pro)
- 自定义属性: 可以为产品添加自定义属性,例如颜色、尺寸等。
- 批量更新: 可以批量更新产品的价格、库存等信息。
- 导入/导出: 支持从 CSV 文件导入产品数据,以及将产品数据导出为 CSV 文件。
示例代码 (Python):
def get_product_details(product_id):
"""
获取指定产品 ID 的产品详情。
Args:
product_id: 产品的 ID。
Returns:
一个包含产品详情的字典,如果产品不存在则返回 None。
"""
# 这里是获取产品详情的示例代码,需要根据实际情况进行修改。
product = database.get_product(product_id)
if product:
return {
"name": product["name"],
"description": product["description"],
"price": product["price"],
"stock": product["stock"]
}
else:
return None
# 示例用法
product_id = %d
product_details = get_product_details(product_id)
if product_details:
print(f"产品名称: {product_details['name']}")
print(f"产品描述: {product_details['description']}")
print(f"产品价格: {product_details['price']}")
print(f"产品库存: {product_details['stock']}")
else:
print(f"产品 ID {product_id} 不存在。")
API 文档:
请参考 API 文档 获取更多关于产品 API 的信息。
常见问题:
- 如何上传产品图片? 请参考 "产品管理" 部分的 "添加产品" 步骤。
- 如何修改产品价格? 请点击产品列表中的 "编辑" 按钮,修改 "价格" 字段。
- Pro 版本有哪些优势? Pro 版本提供了更多高级功能,例如自定义属性、批量更新和导入/导出功能。
联系我们:
如果您有任何问题,请联系我们的技术支持团队。 邮箱地址: support@example.com
产品管理
本页面描述了如何管理产品。
产品管理功能
- 搜索产品:
Search Products - 查看产品:
View Product - 编辑产品:
Edit Product - 批量编辑:
Bulk Edit - 删除产品
- 导入产品 CSV:
Import products CSV - 管理产品图片
- 管理产品库存:
Inventory - 管理产品属性:
Product Attributes - 添加简单产品:
Add simple product - 添加可变产品:
Variable Product - 添加虚拟产品:
Virtual - 添加可下载产品
- 管理产品评论
- 交叉销售:
Cross-sell - 查看专业版:
View Pro - 回收站:
Trash - 阻止:
Block - 链接:
Link - 产品:
Product - 所有产品:
All Products - 详情:
Details - 评论:
Reviews
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Products | View all products |
merchant/product-search.spec.js |
| Merchant | Products | Search products |
merchant/product-search.spec.js |
| Merchant | Products | Add simple product |
merchant/product-create-simple.spec.js |
| Merchant | Products | Add variable product |
merchant/products/add-variable-product/create-variable-product.spec.js |
| Merchant | Products | Edit product details |
merchant/product-edit.spec.js |
| Merchant | Products | Add virtual product |
merchant/product-create-simple.spec.js |
| Merchant | Products | Import products CSV |
merchant/product-import-csv.spec.js |
| Merchant | Products | Add downloadable product |
merchant/product-create-simple.spec.js |
| Merchant | Products | View product reviews list |
merchant/product-reviews.spec.js |
| Merchant | Products | View all products reviews list |
merchant/product-reviews.spec.js |
| Merchant | Products | Edit product review |
merchant/product-reviews.spec.js |
| Merchant | Products | Trash product review |
merchant/product-reviews.spec.js |
| Merchant | Products | Bulk edit products |
merchant/product-edit.spec.js |
| Merchant | Products | Remove products |
merchant/product-delete.spec.js |
| Merchant | Products | Manage product images |
merchant/product-images.spec.js |
| Merchant | Products | Manage product inventory |
merchant/product-create-simple.spec.js |
| Merchant | Products | Manage product attributes |
merchant/product-create-simple.spec.js |
| Merchant | Products | Manage global attributes |
|
| Merchant | Products | Add up-sell |
products/product-linked-products.spec.js |
| Merchant | Products | Add cross-sell |
products/product-linked-products.spec.js |
| Merchant | Products (New) | Disable new product experience |
merchant/products/block-editor/disable-block-product-editor.spec.js |
| Merchant | Products (New) | Add simple product |
merchant/products/block-editor/create-simple-product-block-editor.spec.js |
| Merchant | Products (New) | Edit simple product |
merchant/products/block-editor/product-edit-block-editor.spec.js |
| Merchant | Products (New) | Manage product images |
merchant/products/block-editor/product-images-block-editor.spec.js |
| Merchant | Products (New) | Manage product inventory |
merchant/products/block-editor/product-inventory-block-editor.spec.js |
| Merchant | Products (New) | Manage product attributes |
merchant/products/block-editor/product-attributes-block-editor.spec.js |
商家 - 订单
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | 订单 | 查看所有订单 | merchant/order-status-filter.spec.js |
| 商家 | 订单 | 能够创建新的基本订单 | merchant/order-edit.spec.js |
| 商家 | 订单 | 查看单个订单 | merchant/order-edit.spec.js |
| 商家 | 订单 | 将订单状态更新为已完成 | merchant/order-edit.spec.js |
| 商家 | 订单 | 将订单状态更新为已取消 | merchant/order-edit.spec.js |
| 商家 | 订单 | 更新订单详情 | merchant/order-edit.spec.js |
| 商家 | 订单 | 客户支付页面 | merchant/customer-payment-page.spec.js |
| 商家 | 订单 | 退款订单 | merchant/order-refund.spec.js |
| 商家 | 订单 | 应用优惠券 | merchant/order-coupon.spec.js |
| 商家 | 订单 | 能够创建复杂的新的订单 - 多个产品类型和税类 | merchant/create-order.spec.js |
| 商家 | 订单 | 搜索订单 | merchant/order-search.spec.js |
| 商家 | 订单 | 根据订单状态过滤订单 | merchant/order-status-filter.spec.js |
| 商家 | 订单 | 批量更改订单状态 | merchant/order-bulk-edit.spec.js |
| 商家 | 订单 | 添加订单备注 | merchant/order-edit.spec.js |
商家 - 客户
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| 商家 | 客户 | 显示客户列表 | merchant/customer-list.spec.js |
Merchant - 邮件
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Merchant | 邮件 | 接收并检查新订单邮件的内容 | merchant/order-emails.spec.js |
| Merchant | 邮件 | 接收并检查已取消订单邮件的内容 | merchant/order-emails.spec.js |
| Merchant | 邮件 | 接收并检查失败订单邮件的内容 | merchant/order-emails.spec.js |
| Merchant | 邮件 | 重新发送新订单邮件 | merchant/order-emails.spec.js |
| Merchant | 邮件 | 通过邮件向客户发送发票/订单详情 | merchant/order-emails.spec.js |
Merchant - 插件
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Merchant | 插件 | 可以更新 WooCommerce | smoke-tests/update-woocommerce.spec.js |
Merchant - 我的订阅
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Merchant | 我的订阅 | 可以启动 WooCommerce.com 连接 | merchant/settings-woo-com.spec.js |
Merchant - 网页
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Merchant | 网页 | 可以创建新的网页 | merchant/create-page.spec.js |
Merchant - 文章
| 用户类型 | 流程区域 | 流程名称 | 测试文件 |
|---|---|---|---|
| Merchant | 文章 | 可以创建新的文章 | merchant/create-post.spec.js |
撰写高质量的测试说明
简介
在代码提交请求中提供清晰的测试说明是 WooCommerce 中质量工程的第一步,这对于尽早进行测试以及最大限度地减少 WooCommerce 未来版本中意外影响至关重要。
本页面包含以下部分:
什么是测试?
测试是一种方法,我们可以使用它来检查某事物是否满足某些标准。 它通常被定义为一种程序,其中包含将待测系统置于特定状态所需的所有步骤,然后再执行要检查的操作。 因此,一个测试由以下几个阶段组成:
- 前提条件: 执行要检查的操作之前,需要执行的所有步骤,以使系统处于期望的状态。 一个测试可能包含多个前提条件。
- 操作: 这是导致系统中发生我们想要检查的更改的精确步骤。 理想情况下,每个测试应该只覆盖一个方面,因此操作应该只有一个。
- 验证: 与执行操作后,验证结果所需的步骤相关。 一个测试可以验证多个方面。
例如,在将商品添加到购物车的过程中:
- 前提条件 将包括:
- 产品创建过程。
- 以顾客身份登录。
- 访问列出产品的商店页面。
- 操作 将是点击所需产品的“加入购物车”按钮。
- 验证 阶段将包括检查购物车图标(如果有)是否显示 1 个更多商品,以及我们选择的商品是否已包含在购物车中。
明确前提条件、操作和验证对于理解测试的范围非常有益,因为:
- 前提条件 描述了我们必须执行哪些步骤才能成功执行测试。
- 操作 让我们了解测试的目的,换句话说,它是理解我们需要测试的内容的关键。
- 验证 阶段让我们知道在执行测试时应该期望的结果。
在此上下文中,我们将测试说明称为我们需要执行的测试,以验证代码提交请求或发布的更改是否按预期工作。 这意味着测试说明可能引用一个或多个测试,包括正常流程和潜在的边缘情况。
测试说明应该涵盖的内容
如前一部分所述,一个测试(在我们的语境中,一个测试说明)是一种方法,用于检查新的更改或一组更改是否满足某些标准。
因此,一个 Pull Request (PR) 可以包含针对多个场景的测试说明,实际上,建议包含尽可能多的测试说明,以覆盖 PR 中引入的所有更改。 换句话说,请添加尽可能多的测试说明,以覆盖验收标准,将验收标准理解为_软件产品必须满足的条件,才能被用户、客户或其他利益相关者接受_,或者,在 PR 的语境下,PR 必须满足的条件,才能被用户、开发者和 WooCommerce 社区接受,如要求所述。
撰写高质量测试说明的流程
- 概述您想要覆盖的用户流程。
- 定义执行测试说明的环境(服务器、PHP 版本、WP 版本、必需的插件等),并像从全新安装开始一样撰写测试说明。
- 识别前提条件、操作和验证步骤。
- 撰写尽可能多的前提条件,以解释如何设置 WooCommerce 的状态,以便您可以执行所需的操作来测试每个流程。
- 尽量详细地解释用户在 WooCommerce 中需要执行的交互操作。
- 如果某个用户流程在公开指南中有详细说明,您可以直接在测试说明中链接到该指南,而无需编写多个步骤。 例如,“请按照测试账户文档中提到的步骤启用 WooCommerce Payments 的开发模式”。
- 撰写操作步骤,该步骤应涵盖我们希望在此用户流程中测试的特定操作。
- 撰写尽可能多的验证步骤,以评估实际结果是否符合预期。
- 请记住,仅检查验证此更改是否正常运行所需的步骤。
撰写高质量测试说明的注意事项
- 以一种所有人都能理解和遵循的方式定义测试说明,即使是那些不熟悉 WooCommerce 的人。
- 务必详细描述每一个细节,避免假设知识,因为读者的范围可能很广,有些人可能不了解您所假设的概念。例如,不要说“启用 [x] 实验”,而应该说:
- 安装 WooCommerce Beta Tester 插件。
- 访问 `工具 > WCA 测试助手 > 实验`。
- 切换 [x] 实验。
- 始终尝试详细说明用户应该前往哪里,例如,不要说“以管理员身份访问订单页面”,而应该说“访问 [url]”或“访问 WooCommerce > 订单”。
- 尽量使用真实的测试数据。例如,不要说“输入产品的名称”,而应该说“输入 '蓝色 T 恤' 作为产品名称”。这会使其更易于理解,并消除与假设知识相关的潜在疑问。
- 请确保您的测试说明保持更新,如果它们在新的提交中变得过时,请及时更新。
- 如果测试说明需要添加自定义代码,请提供代码片段。
- 如果测试说明需要安装插件,请提供指向该插件的链接,或用于安装的 zip 文件。
- 如果测试说明需要访问 API 接口,请提供指向接口文档的链接。
- 理想情况下,请提供截图和/或视频,以支持测试说明所解释的内容。如果您使用指向协作工具的链接,也请为那些无法访问这些工具的人提供相应的截图/视频。
示例
优质的测试说明示例
示例 1

示例 2

改进真实测试的说明
在这一部分,您将看到一些真实测试说明的例子,这些例子有改进的空间(前)以及我们如何对其进行调整(后)。
前:

后:

改进:

前:

后:

改进:

前:

后:

改进:

WooCommerce 核心关键流程
我们已经确定了我们认为在 WooCommerce 核心中最关键的用户流程。这些流程将帮助我们聚焦并优先安排测试工作。它们还将帮助我们评估更改的影响和问题的优先级。
随着平台的发展,这些流程将持续演进,流程会被更新、添加或重新确定优先级。
Shopper critical flow areas
- Shopper > Shop
- Shopper > Product
- Shopper > Cart
- Shopper > Checkout
- Shopper > Email
- Shopper > My Account
Merchant critical flow areas
- Merchant > Onboarding
- Merchant > Dashboard
- Merchant > Settings
- Merchant > Coupons
- Merchant > Marketing
- Merchant > Analytics
- Merchant > Products
- Merchant > Orders
- Merchant > Customers
- Merchant > Email
- Merchant > Plugins
- Merchant > My Subscriptions
- Merchant > Pages
- Merchant > Posts
Shopper - Shop
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | Shop | Search Store | shopper/shop-search-browse-sort.spec.js |
| Shopper | Shop | Browse by categories | shopper/shop-search-browse-sort.spec.js |
| Shopper | Shop | Can sort items | shopper/shop-search-browse-sort.spec.js |
| Shopper | Shop | Add Simple Product to Cart (from shop page) | shopper/cart.spec.js |
| Shopper | Shop | Display shop catalog | shopper/shop-search-browse-sort.spec.js |
| Shopper | Shop | Products by tag | shopper/product-tags-attributes.spec.js |
| Shopper | Shop | Products by attribute | shopper/product-tags-attributes.spec.js |
| Shopper | Shop | Use product filters | shopper/shop-products-filer-by-price.spec.js |
Shopper - Product
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | Product | Add Simple Product to Cart | shopper/product-simple.spec.js |
| Shopper | Product | Add Grouped Product to Cart | shopper/product-grouped.spec.js |
| Shopper | Product | Variable Product info updates depending on variation | shopper/product-variable.spec.js |
| Shopper | Product | Add Variable Product to Cart | shopper/product-variable.spec.js |
| Shopper | Product | Display up-sell product | products/product-linked-products.spec.js |
| Shopper | Product | Display related products | products/product-linked-products.spec.js |
| Shopper | Product | Display reviews | merchant/product-reviews.spec.js |
| Shopper | Product | Add review | merchant/product-reviews.spec.js |
| Shopper | Product | View product images | shopper/product-simple.spec.js |
| Shopper | Product | View product descriptions | shopper/product-simple.spec.js |
Shopper - Cart
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | Cart | Add to cart redirects to cart when enabled | shopper/cart-redirection.spec.js |
| Shopper | Cart | View cart | shopper/cart.spec.js |
| Shopper | Cart | Update product quantity within limits | shopper/cart.spec.js |
| Shopper | Cart | Remove products from cart | shopper/cart.spec.js |
| Shopper | Cart | Apply all coupon types | shopper/cart-coupons.spec.js |
| Shopper | Cart | Display shipping options by address | shopper/calculate-shipping.spec.js |
| Shopper | Cart | View empty cart | shopper/cart.spec.js |
| Shopper | Cart | Display correct tax | shopper/cart-checkout-calculate-tax.spec.js |
| Shopper | Cart | Respect coupon usage constraints | shopper/cart-checkout-coupons.spec.js |
| Shopper | Cart | Display cross-sell products | products/product-linked-products.spec.js |
| Shopper | Cart | Proceed to checkout | shopper/checkout.spec.js |
Shopper - Checkout
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | Checkout | Correct item in Order Review | shopper/checkout.spec.js |
| Shopper | Checkout | Can add shipping address | shopper/checkout.spec.js |
| Shopper | Checkout | Guest can place order | shopper/checkout.spec.js |
| Shopper | Checkout | Create an account | shopper/checkout-create-account.spec.js |
| Shopper | Checkout | Login to existing account | shopper/checkout-login.spec.js |
| Shopper | Checkout | Existing customer can place order | shopper/checkout.spec.js |
| Shopper | Checkout | Use all coupon types | shopper/checkout-coupons.spec.js |
| Shopper | Checkout | View checkout | shopper/checkout.spec.js |
| Shopper | Checkout | Receive warnings when form is incomplete | shopper/checkout.spec.js |
| Shopper | Checkout | Add billing address | shopper/checkout.spec.js |
| Shopper | Checkout | Respect coupon usage constraints | shopper/cart-checkout-coupons.spec.js |
| Shopper | Checkout | Display correct tax in checkout | shopper/cart-checkout-calculate-tax.spec.js |
| Shopper | Checkout | View order confirmation page | shopper/checkout.spec.js |
Shopper - Email
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | Customer Account Emails Received | shopper/account-email-receiving.spec.js | |
| Shopper | Customer Order Detail Emails Received | shopper/order-email-receiving.spec.js |
Shopper - My Account
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Shopper | My Account | Create an account | shopper/my-account-create-account.spec.js |
| Shopper | My Account | Login to existing account | shopper/my-account.spec.js |
| Shopper | My Account | View Account Details | shopper/my-account.spec.js |
| Shopper | My Account | Update Addresses | shopper/my-account-addresses.spec.js |
| Shopper | My Account | View Orders | shopper/my-account-pay-order.spec.js |
| Shopper | My Account | Pay for Order | shopper/my-account-pay-order.spec.js |
| Shopper | My Account | View Downloads | shopper/my-account-downloads.spec.js |
Merchant - Onboarding
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Core Profiler | Introduction & opt-in | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | User profile information | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | Business information | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | Extensions page | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | WooPayments included in extensions for eligible criteria | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | WooPayments not included in extensions for ineligible criteria | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | Install all default extensions | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | Complete site setup | activate-and-setup/core-profiler.spec.js |
| Merchant | Core Profiler | Skip introduction and confirm business location | activate-and-setup/core-profiler.spec.js |
Merchant - Dashboard
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | WC Home | Completing profiler redirects to home | |
| Merchant | WC Home | Complete all steps on task list | |
| Merchant | WC Home | Hide the task list | |
| Merchant | WC Home | Store management displayed after task list finished | |
| Merchant | WC Home | Direct access to analytics reports from stats overview | |
| Merchant | WC Home | Preserve task list completion status after upgrade | |
| Merchant | WC Home | Interact with extended task list | |
| Merchant | Activity Panel | Interact with activity button | |
| Merchant | Inbox | Interact with notes and perform CTAs | |
| Merchant | Inbox | Dismiss single note and all notes |
Merchant - Settings
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Settings | Update General Settings | merchant/settings-general.spec.js |
| Merchant | Settings | Add Tax Rates | merchant/settings-tax.spec.js |
| Merchant | Settings | Add Shipping Zones | merchant/create-shipping-zones.spec.js |
| Merchant | Settings | Add Shipping Classes | merchant/create-shipping-classes.spec.js |
| Merchant | Settings | Enable local pickup for checkout block | merchant/settings-shipping.spec.js |
| Merchant | Settings | Update payment settings | admin-tasks/payment.spec.js |
| Merchant | Settings | Handle Product Brands | merchant/create-product-brand.spec.js |
Merchant - Coupons
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Coupons | Add all coupon types | merchant/create-coupon.spec.js |
| Merchant | Coupons | Add restricted coupon | merchant/create-restricted-coupons.spec.js |
Merchant - Marketing
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Marketing | Display marketing overview | admin-marketing/overview.spec.js |
Merchant - Analytics
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Analytics | View revenue report | admin-analytics/analytics.spec.js |
| Merchant | Analytics | View overview report | admin-analytics/analytics-overview.spec.js |
| Merchant | Analytics | Confirm correct summary numbers on overview report | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Use date filter on overview page | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Customize performance indicators on overview page | admin-analytics/analytics-overview.spec.js |
| Merchant | Analytics | Use date filter on revenue report | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Download revenue report as CSV | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Use advanced filters on orders report | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Analytics settings | admin-analytics/analytics-data.spec.js |
| Merchant | Analytics | Set custom date range on revenue report | admin-analytics/analytics-data.spec.js |
商家 - 产品
本页面展示了商家的产品列表。
产品管理
- 添加产品: 点击 "添加产品" 按钮,可以创建一个新的产品。
- 编辑产品: 点击产品列表中的 "编辑" 按钮,可以修改产品的详细信息。
- 删除产品: 点击产品列表中的 "删除" 按钮,可以删除产品。 删除操作不可逆。
- 批量操作: 支持批量上传和删除产品。
产品详情
每个产品包含以下信息:
- 产品名称: 产品的名称。
- 产品描述: 产品的详细描述。
- 产品图片: 产品的图片。
- 价格: 产品的价格。
- 库存: 产品的库存数量。
- 分类: 产品的分类。
- SKU: 产品的唯一标识符。
- 状态: 产品的状态(例如:已上架、已下架)。
产品状态管理
- 上架/下架: 可以对产品进行上架和下架操作,控制产品在商店的显示。
高级功能 (仅限 Pro)
- 自定义属性: 可以为产品添加自定义属性,例如颜色、尺寸等。
- 批量更新: 可以批量更新产品的价格、库存等信息。
- 导入/导出: 支持从 CSV 文件导入产品数据,以及将产品数据导出为 CSV 文件。
示例代码 (Python):
def get_product_details(product_id):
"""
获取指定产品 ID 的产品详情。
Args:
product_id: 产品的 ID。
Returns:
一个包含产品详情的字典,如果产品不存在则返回 None。
"""
# 这里是获取产品详情的示例代码,需要根据实际情况进行修改。
product = database.get_product(product_id)
if product:
return {
"name": product["name"],
"description": product["description"],
"price": product["price"],
"stock": product["stock"]
}
else:
return None
# 示例用法
product_id = %d
product_details = get_product_details(product_id)
if product_details:
print(f"产品名称: {product_details['name']}")
print(f"产品描述: {product_details['description']}")
print(f"产品价格: {product_details['price']}")
print(f"产品库存: {product_details['stock']}")
else:
print(f"产品 ID {product_id} 不存在。")
API 文档:
请参考 API 文档 获取更多关于产品 API 的信息。
常见问题:
- 如何上传产品图片? 请参考 "产品管理" 部分的 "添加产品" 步骤。
- 如何修改产品价格? 请点击产品列表中的 "编辑" 按钮,修改 "价格" 字段。
- Pro 版本有哪些优势? Pro 版本提供了更多高级功能,例如自定义属性、批量更新和导入/导出功能。
联系我们:
如果您有任何问题,请联系我们的技术支持团队。 邮箱地址: support@example.com
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Products | View all products | merchant/product-search.spec.js |
| Merchant | Products | Search products | merchant/product-search.spec.js |
| Merchant | Products | Add simple product | merchant/product-create-simple.spec.js |
| Merchant | Products | Add variable product | merchant/products/add-variable-product/create-variable-product.spec.js |
| Merchant | Products | Edit product details | merchant/product-edit.spec.js |
| Merchant | Products | Add virtual product | merchant/product-create-simple.spec.js |
| Merchant | Products | Import products CSV | merchant/product-import-csv.spec.js |
| Merchant | Products | Add downloadable product | merchant/product-create-simple.spec.js |
| Merchant | Products | View product reviews list | merchant/product-reviews.spec.js |
| Merchant | Products | View all products reviews list | merchant/product-reviews.spec.js |
| Merchant | Products | Edit product review | merchant/product-reviews.spec.js |
| Merchant | Products | Trash product review | merchant/product-reviews.spec.js |
| Merchant | Products | Bulk edit products | merchant/product-edit.spec.js |
| Merchant | Products | Remove products | merchant/product-delete.spec.js |
| Merchant | Products | Manage product images | merchant/product-images.spec.js |
| Merchant | Products | Manage product inventory | merchant/product-create-simple.spec.js |
| Merchant | Products | Manage product attributes | merchant/product-create-simple.spec.js |
| Merchant | Products | Manage global attributes | |
| Merchant | Products | Add up-sell | products/product-linked-products.spec.js |
| Merchant | Products | Add cross-sell | products/product-linked-products.spec.js |
| Merchant | Products (New) | Disable new product experience | merchant/products/block-editor/disable-block-product-editor.spec.js |
| Merchant | Products (New) | Add simple product | merchant/products/block-editor/create-simple-product-block-editor.spec.js |
| Merchant | Products (New) | Edit simple product | merchant/products/block-editor/product-edit-block-editor.spec.js |
| Merchant | Products (New) | Manage product images | merchant/products/block-editor/product-images-block-editor.spec.js |
| Merchant | Products (New) | Manage product inventory | merchant/products/block-editor/product-inventory-block-editor.spec.js |
| Merchant | Products (New) | Manage product attributes | merchant/products/block-editor/product-attributes-block-editor.spec.js |
Merchant - Orders
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Orders | View all orders | merchant/order-status-filter.spec.js |
| Merchant | Orders | Can add new order basic | merchant/order-edit.spec.js |
| Merchant | Orders | View single order | merchant/order-edit.spec.js |
| Merchant | Orders | Update order status to completed | merchant/order-edit.spec.js |
| Merchant | Orders | Update order status to cancelled | merchant/order-edit.spec.js |
| Merchant | Orders | Update order details | merchant/order-edit.spec.js |
| Merchant | Orders | Customer payment page | merchant/customer-payment-page.spec.js |
| Merchant | Orders | Refund order | merchant/order-refund.spec.js |
| Merchant | Orders | Apply coupon | merchant/order-coupon.spec.js |
| Merchant | Orders | Can add new order complex - multiple product types & tax classes | merchant/create-order.spec.js |
| Merchant | Orders | Search orders | merchant/order-search.spec.js |
| Merchant | Orders | Filter orders by order status | merchant/order-status-filter.spec.js |
| Merchant | Orders | Bulk change order status | merchant/order-bulk-edit.spec.js |
| Merchant | Orders | Add order notes | merchant/order-edit.spec.js |
Merchant - Customers
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Customers | Display customer list | merchant/customer-list.spec.js |
Merchant - Email
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Receive and check content of new order email | merchant/order-emails.spec.js | |
| Merchant | Receive and check content of cancelled order email | merchant/order-emails.spec.js | |
| Merchant | Receive and check content of failed order email | merchant/order-emails.spec.js | |
| Merchant | Resent new order email | merchant/order-emails.spec.js | |
| Merchant | Send invoice/order details to customer via Email | merchant/order-emails.spec.js |
Merchant - Plugins
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Plugins | Can update WooCommerce | smoke-tests/update-woocommerce.spec.js |
Merchant - My Subscriptions
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | My Subscriptions | Can initiate WooCommerce.com Connection | merchant/settings-woo-com.spec.js |
Merchant - Pages
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Pages | Can create a new page | merchant/create-page.spec.js |
Merchant - Posts
| User Type | Flow Area | Flow Name | Test File |
|---|---|---|---|
| Merchant | Posts | Can create a new post | merchant/create-post.spec.js |
可访问性最佳实践
在世界许多地方,电子商务商店需要对残疾人士开放。作为 WooCommerce 扩展开发者,您的代码直接影响使用您的扩展的商店的可访问性,并可能影响商家遵守可访问性法律的情况。
本页面是为希望确保其扩展符合可访问性标准和最佳实践的开发者提供的资源。建议所有 WooCommerce 扩展都应遵循可访问性最佳实践,以提供最佳的商家和客户体验。
可访问性法律
有两个例子说明了要求电子商务网站具有可访问性的法律,包括美国的《美国残疾人法案》(Americans with Disabilities Act (ADA))和欧盟的《欧洲可访问性法案》(European Accessibility Act (EAA)),该指令适用于所有欧盟成员国。澳大利亚、加拿大、以色列以及许多其他国家也有要求网站可访问性的法律。W3C 维护着一份关于全球网站可访问性法律的列表,如果您想了解您所在国家/地区的法律,可以查阅该列表。
大多数法律要求网站符合 Web 内容可访问性指南 (WCAG),作为衡量可访问性的标准。为了确保商家可以在其网站上使用您的扩展,您的扩展也应符合 WCAG 标准。
如果您的扩展不符合 WCAG 标准,您可能会收到商家关于可访问性问题的投诉。您也可能因您的扩展导致的可访问性问题而成为诉讼或法律案件的被告。
Web 内容可访问性指南 (WCAG)
Web 内容可访问性指南 (WCAG) 是国际公认的标准,旨在使网站对所有人开放,包括残疾人士。WCAG 由 成功标准(具体的、可测试的规则)组成,这些标准涵盖四个关键原则:
四个关键原则
-
可感知 (Perceivable) 内容应以用户可以感知的方式呈现,即使他们不具备所有五种感官。信息应可以从一种形式转换为另一种形式(例如,图像的文本替代说明或视频的字幕)。
-
可操作 (Operable) 用户应能够使用各种设备(例如,仅使用键盘或不使用鼠标的屏幕阅读器)轻松地与网站进行交互,并且不应存在时间敏感的操作。
-
可理解 (Understandable) 内容和界面应清晰且一致,使用简单的语言和可预测的导航。
-
稳健 (Robust) 网站应与辅助技术兼容,并在不同的设备上正常工作。
兼容性级别
WCAG 有三个兼容性级别:
- Level A – 基础
- Level AA – 中级 (大多数法律要求)
- Level AAA – 最高
大多数法规要求 Level AA,这意味着您需要满足所有 A 和 AA 的成功标准。
当前版本
WCAG 的当前版本是 2.2。 扩展开发者应努力达到 WCAG 2.2 Level AA 的兼容性,这是一种最佳实践。
手动兼容性测试
在您设计和开发新功能时,对您的扩展进行 WCAG 兼容性 测试非常重要。 针对可访问性的测试与针对安全性或 WordPress 编码标准的测试同样重要。 如果您之前没有对您的扩展进行可访问性测试,请立即开始测试,并在未来的版本中添加可访问性修复。
自动化测试
开始可访问性测试最简单的方法是使用自动化测试工具。 自动化工具可以快速识别诸如空按钮、模糊链接、颜色对比度问题、缺少替代文本等问题。
Accessibility Checker 是一个免费的 WordPress 插件,您可以使用它来测试您的扩展。 简单地将其安装在您的测试环境中,并将由您的扩展创建的区块或短代码添加到网页中。 当您保存网页时,Accessibility Checker 将扫描区块或渲染的短代码,并提供一个问题列表供您解决。
WAVE 浏览器扩展 是另一个免费的自动化测试工具。 此浏览器扩展程序可用于任何网站,如果您想在您扩展的后台页面上查找可访问性问题,它会非常有用。
键盘测试
在解决自动化测试中出现的问题后,下一步是确保您的扩展程序可以在没有鼠标的情况下,仅使用键盘进行操作。
要测试您的扩展程序的键盘可访问性,请访问由您的扩展程序控制的测试站点的相关部分。 使用 Tab 键,在网页上向前移动,并确保以下内容为真:
- 所有交互式组件(按钮、链接、输入框等)都可以通过按下 Tab 键访问。
- 焦点应从左到右,从上到下,以直观的方式在页面上移动。
- 您可以通过按下 Shift + Tab 向后移动组件。
- 不存在键盘陷阱。 键盘陷阱是指焦点停留在某个元素上,然后无法向前或向后移动。
- 所有交互式组件都应具有可见的焦点轮廓。 此外,请确认您在样式表中是否从未将
:focus设置为outline:none;或outline:0;。 永远不应该移除焦点轮廓。 - 如果一个按钮触发模态框或对话框,焦点应移动到对话框中,并且不应允许在关闭对话框之前通过 Tab 键退出对话框。
- 按钮应可以通过空格键和回车键触发。
- 链接应可以通过回车键触发。
在前端和管理后台测试您的扩展程序的各个方面,以确保在没有鼠标的情况下实现完整的功能。
缩放时的测试
确保您的扩展程序可以被视力较弱的用户在浏览器缩放的情况下使用。 将浏览器的缩放设置为 200% 和 400%,并确保没有内容重叠或丢失,并且在站点缩放时,扩展程序的组件可以正常使用。
屏幕阅读器测试
请熟悉屏幕阅读器,这是一种辅助技术,供视力障碍人士使用。使用屏幕阅读器来测试您的扩展程序。以下是两个可用于测试的免费屏幕阅读器:
- VoiceOver: 如果您使用的是 Mac,VoiceOver 已经内置于您的计算机中,是一个很好的入门选择,但它不是视力障碍桌面用户首选的屏幕阅读器。
- NVDA: NVDA 是一款免费、开源的屏幕阅读器,您可以下载并在您的 PC 上使用。这是测试的首选屏幕阅读器,因为大多数视力障碍人士使用 Windows。
要测试您的扩展程序的屏幕阅读器可访问性,请启用屏幕阅读器,并使用键盘导航网页。让屏幕阅读器朗读整个网页,并注意以下内容:
- 所有内容和元素都被朗读出来,没有遗漏任何重要信息。
- 图像和图形具有准确的描述。
- 装饰性图像会被跳过。
- 元素具有正确的角色:按钮应该被宣布为按钮,链接应该被宣布为链接,等等。
- 链接和按钮具有描述其用途的名称。
- 表单字段已正确标记。
- 组件的状态(例如,选项卡、折叠、切换按钮)会被宣布为折叠、选中、按下等。
- 屏幕阅读器会宣布状态变化(例如,成功和错误消息,可见产品数量的变化,模态框或对话框的打开等)。
- 隐藏的内容不会被朗读出来。
运动敏感性测试
网站上的动画和运动可能会分散某些用户的注意力,甚至可能导致身体不适。为了确保您的扩展程序符合 WCAG 的运动相关成功标准:
- 为任何持续时间超过 5 秒的自动播放内容提供暂停按钮(例如,视频、背景视频、滑块/轮播图或动画 GIF)。
- 避免闪烁的内容,闪烁频率超过每秒三次,因为它可能会引发癫痫。
- 确保所有动画在用户在他们的操作系统中启用了“减少运动”设置时都被禁用。
您可以测试您的动画是否尊重“首选减少运动”设置,方法是在您的操作系统中启用该设置。以下是操作方法:
- 在 Windows 11 上: 转到 设置 > 可访问性 > 视觉效果 > 动画效果。
- 在 macOS 上: 导航到 系统偏好设置 > 可访问性 > 显示 > 减少运动。
了解更多关于如何编写 prefers-reduced-motion media queries 的信息。
用户测试
考虑邀请实际的残疾用户来测试您的扩展程序的无障碍性。 看到那些依赖屏幕阅读器或其他辅助设备的用户的体验,可能会非常有启发性。 询问您的客户群,看看您是否已经有残疾人士可以在您的受众中提供测试和反馈。 这里有一个很好的资源,介绍了如何进行用户测试。
如果您不想自己进行用户测试,有一些WooExperts可以提供帮助。
其他注意事项
使您的网站无障碍
除了测试您的扩展程序的无障碍最佳实践之外,您还应该考虑您自己的网站和文档的无障碍性。 如果您的业务达到某些收入门槛,那么人们购买您产品的电子商务商店必须是无障碍的,并且符合 WCAG 标准。
为您的视频添加字幕
如果您的文档包含视频,则这些视频必须带有字幕,并包含文字稿。 这对于确保每个人都可以访问您的文档并学习如何使用您的扩展程序非常重要。
指导您的客户
即使您的扩展程序是完全无障碍的,商家在配置您的扩展程序或添加内容时也可能会引入无障碍问题。 尽可能定义无障碍的默认设置。 例如,您的扩展程序中的默认颜色始终应满足 WCAG AA 颜色对比度要求。 商家可能会更改这些颜色,使其组合不符合对比度要求,但您可以说您的扩展程序是“无障碍就绪”的,如果默认设置符合要求。
考虑在管理后台添加功能,当商家做出可能对无障碍性产生负面影响的选择时,向他们发出警告。 例如,您可以标记不符合对比度要求的颜色组合,类似于 WordPress 核心中的实现方式。 您还可以警告商家关于其他问题,例如空字段标签、标题顺序错误、空的替代文本,或者选择您必须维护以实现向后兼容性,但已知不符合无障碍要求的设置。
创建可访问性合规性报告
许多组织,尤其是在政府和教育领域,在购买软件之前通常需要一份可访问性合规性报告 (ACR)。 如果您的扩展程序销售给大型企业、政府或教育机构,一份 ACR 可以加快采购流程。
可访问性合规性报告是一份文档,它概述了数字产品的可访问性合规情况,并符合公认的可访问性标准,例如 WCAG、美国《第 508 条》和欧洲的 EN 301 549 可访问性标准。
ACR 是使用自愿产品可访问性模板 (VPAT) 创建的,VPAT 是一种用于评估和报告可访问性功能的标准化格式。 您可以免费下载此模板并自行填写,或者聘请可访问性专家来审核您的扩展程序,并为您完成 VPAT。
获取合规性方面的帮助
WCAG 合规性不必让人感到不知所措! 您可以一次修复一个问题,逐步改进您的扩展程序。 但是,如果不需要记住 WCAG 或学习如何进行测试,可访问性工作会更快。 考虑聘请可访问性专家来帮助审核或进行用户测试您的扩展程序。 合适的公司或顾问将帮助您快速找到问题,确定修复优先级,并培训您的团队,以便将来减少可访问性问题。
您可以在我们的 WooExperts 目录 中找到专注于可访问性的开发者。
了解更多关于可访问性的知识
如果您想了解更多关于网站可访问性的知识,我们推荐以下资源:
WooCommerce 扩展的兼容性和互操作性
确保您的 WooCommerce 扩展与核心平台、各种组件和其他扩展兼容,对于为用户提供无缝体验至关重要。本文档涵盖了兼容性的重要性、自我声明兼容性检查的流程、手动测试兼容性问题的步骤以及故障排除常见问题的指南。
兼容性的重要性
兼容性确保您的扩展在不同的环境中按预期工作,包括各种版本的 WordPress 和 WooCommerce,以及与其他插件和主题。确保兼容性对于以下方面至关重要:
- 用户体验:防止可能导致功能问题或网站停机的冲突。
- 采用和留存:如果用户确信扩展具有兼容性,他们更有可能安装和保持更新。
- 安全性和性能:兼容的扩展不太可能引入漏洞或降低网站性能。
自我声明的兼容性检查
开发者应声明其扩展与最新版本的 WordPress 和 WooCommerce 兼容,以及与特定组件(如购物车和结账块、高性能订单存储 (HPOS)、产品编辑器和站点编辑器)兼容。此过程包括:
- 测试:在发布之前,使用最新版本的 WordPress 和 WooCommerce 以及指定的组件对扩展进行全面测试。
- 声明:更新扩展的文档和元数据,以反映其与这些平台和组件的兼容性。
- 沟通:在扩展的变更日志、网站或代码库中告知用户兼容的版本。
手动兼容性测试
手动测试对于识别和解决潜在的兼容性问题至关重要。请按照以下步骤进行有效的手动兼容性测试:
- 设置测试环境,该环境应尽可能模拟典型的用户设置,包括最新版本的 WordPress 和 WooCommerce。
- 使用核心组件进行测试:验证扩展在核心组件(如购物车和结账块、HPOS、产品编辑器和站点编辑器)上的功能。
- 插件之间的兼容性:激活您的扩展,并与其他常用的插件一起使用,以检查是否存在冲突。
- 主题兼容性:使用多个流行主题测试您的扩展,以确保其正常工作并保持一致的外观。
故障排除和解决兼容性问题
即使经过彻底的测试,也可能出现兼容性问题。以下是常见问题以及解决步骤:
与其他扩展的冲突
- 诊断: 使用诸如 Health Check & Troubleshooting 插件 之类的工具来识别冲突的插件。
- 解决: 联系其他插件的开发者寻求合作,或者在您的扩展中实现条件逻辑,以避免冲突。
主题兼容性问题
- 诊断: 检查当您的扩展与不同的主题一起使用时,是否存在样式或布局问题。
- 解决: 使用更通用的 CSS 选择器,并提供配置选项以实现更好的主题集成。
破坏兼容性的更新
- 预防措施: 订阅 WooCommerce 开发者博客,以随时了解即将发生的更改。
- 快速修复: 准备补丁或小版本更新,以便在核心更新后尽快解决兼容性问题。
启用多个扩展时没有错误
- 最佳实践: 定期在多插件环境中测试您的扩展,以确保它不会引起或受到冲突的影响。
结论
维护兼容性和互操作性是一项持续的努力,需要定期测试、更新以及与您的用户和更广泛的开发者社区进行沟通。 通过遵循这些指南,您可以提高 WooCommerce 扩展的可靠性、用户满意度和成功率。
WooCommerce 扩展开发最佳实践
想创建一个插件来扩展 WooCommerce 吗? 您来对地方了。
WooCommerce 扩展与普通的 WordPress 插件相同。 更多信息,请访问 撰写插件。
您的 WooCommerce 扩展应该:
- 遵循所有 WordPress 插件的编码标准,以及 最佳实践指南,以确保在 WordPress 系统中与其他 WordPress 插件和谐共存。
- 具有单一的核心功能,并尽可能地使用 WooCommerce 的功能。
- 不做任何恶意、非法或不诚实的事情,例如,通过第三方系统插入垃圾链接或可执行代码,除非这些行为是服务的一部分或明确允许在服务的服务条款中。
- 不应破坏或覆盖核心 Marketplace 的连接,例如,扩展程序不能创建带有品牌名称的顶级菜单项,也不能引入自己的遥测数据。
- 遵循 WooCommerce 的 兼容性和互操作性指南。
商家每天都会使用 WooCommerce 扩展,他们应该在使用过程中获得统一且愉快的体验,而不会因为广告而干扰他们的 WP 管理界面或商店。
最佳实践
本节介绍一些最佳实践,以帮助您更好地使用该系统。
通用原则
- 模块化设计: 将系统分解为独立的、可重用的模块,以提高可维护性和可扩展性。
- 清晰的命名: 使用具有描述性的名称来命名变量、函数和类,以提高代码的可读性。
- 错误处理: 实施适当的错误处理机制,以确保系统在出现错误时能够优雅地恢复。
- 代码注释: 添加清晰、简洁的注释,以解释代码的意图和功能。
- 版本控制: 使用版本控制系统(例如 Git)来跟踪代码的更改,并方便协作。
配置
- 使用配置文件: 将配置参数存储在配置文件中,而不是硬编码在代码中。
- 环境变量: 使用环境变量来配置敏感信息,例如数据库密码和 API 密钥。
- 默认值: 为配置参数提供合理的默认值,以便在未明确设置时能够正常工作。
性能
- 优化算法: 选择合适的算法,并对其进行优化,以提高性能。
- 缓存: 使用缓存来减少对数据库和其他资源的访问。
- 异步操作: 使用异步操作来避免阻塞主线程。
安全性
- 输入验证: 对所有用户输入进行验证,以防止恶意代码注入。
- 身份验证和授权: 实施强大的身份验证和授权机制,以保护系统资源。
- 加密: 使用加密来保护敏感数据。
示例
以下是一个使用 Python 编写的简单示例,演示了如何使用配置文件:
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# 从配置文件中获取数据库密码
db_password = config['database']['password']
print(f"数据库密码: {db_password}")
config.ini 文件的内容如下:
[database]
password = %s
其他建议
- 阅读官方文档,了解更多关于该系统的详细信息。
- 参考示例代码,学习如何使用该系统的各种功能。
- 参与社区讨论,与其他用户交流经验。
- 定期更新系统,以获取最新的功能和安全补丁。
希望这些最佳实践能够帮助您更好地使用该系统。
- 检查 WooCommerce 是否已启用. 大多数 WooCommerce 插件只有在 WooCommerce 已经启用时才需要运行。 了解如何检查 WooCommerce 是否已启用。
- 主插件文件应采用插件的名称. 例如:一个目录名为
plugin-name的插件,其主文件应命名为plugin-name.php。 - 文本域名应与您的插件目录名称匹配. 例如:一个目录名为
plugin-name的插件,其文本域名应为plugin-name。 请勿使用下划线。 - 国际化: 遵循 WordPress 开发者国际化指南。
- 本地化: 插件代码中的所有文本字符串应使用英语。 这是 WordPress 的默认语言环境,英语始终应该是第一种语言。 如果您的插件面向特定市场(例如西班牙或意大利),请在您的插件包中包含适用于这些语言的翻译文件。 了解更多信息,请查看 使用 Makepot 翻译您的插件。
- 遵循 WordPress PHP 指南. WordPress 有一套 指南,旨在保持所有 WordPress 代码的一致性和易读性。 这包括引号、缩进、花括号样式、简短的 PHP 标签、Yoda 条件、命名约定等等。 请仔细阅读这些指南。
- 尽量避免创建自定义数据库表. 尽可能使用 WordPress 文章类型、分类法 和 选项。 更多信息,请查看我们的 数据存储入门指南。
- 防止数据泄露,确保您没有提供直接访问 PHP 文件的途径。 了解如何操作。
- 所有插件都需要一个标准的 WordPress README 文件。 请参考 WordPress 插件 README 文件标准 中的示例。
- 所有插件都需要一个变更日志文件。 请参考 变更日志文档 中的示例,了解变更日志文件以及不同类型的变更日志条目。
- 遵循我们插件头部注释的约定. 请参考我们的 WordPress 插件头部注释示例,并遵循其中列出的约定,包括:
Author:、Author URI:、Developer:、Developer URI、WC requires at least:、WC tested up to:和Plugin URI:。 - 使其可扩展: 使用 WordPress 的动作和过滤器,允许进行修改/自定义。 如果您的插件生成前端输出,我们建议使用模板引擎,以便用户可以在其主题的 WooCommerce 文件夹中创建自定义模板文件,以覆盖插件的模板文件。 更多信息,请查看 Pippin 关于 使用动作和过滤器编写可扩展插件 的文章。
- 避免使用外部库. 通常不建议使用整个外部库,因为这可能会使产品存在安全漏洞。 如果绝对需要使用外部库,开发人员应仔细考虑所使用的代码,并承担代码的所有权和责任。 尽量只包含库中严格必要的部分,或者使用 WordPress 友好的版本,或者自行构建版本。 例如,如果需要使用文本编辑器,例如 TinyMCE,我们建议使用 WordPress 友好的版本 TinyMCE Advanced。
- 避免使用第三方系统: 允许从已记录的服务加载代码,但通信必须是安全的。 在插件中执行外部代码是不允许的。 禁止使用第三方 CDN 为与服务无关的 JavaScript 和 CSS 提供服务。 不应使用 iframe 连接管理页面。
- 删除未使用的代码. 使用版本控制时,没有理由留下注释掉的代码;它会让人感到不便。 删除它,如果需要,稍后可以重新添加。
- 使用注释 来描述您的代码的功能。 如果您有一个函数,该函数的作用是什么? 您的代码中应该为大多数甚至所有函数都添加注释。 某人/您可能需要修改插件,而注释对于此非常有用。 我们建议使用类似于 WooCommerce 的 PHP 文档块。
- 避免使用“上帝对象”. 上帝对象 是指那些知道或执行过多事情的对象。 面向对象编程的目的是将一个大问题分解成更小的部分。 当函数执行过多操作时,很难理解其逻辑,这会使修复错误变得更加困难。 不要使用大型函数,而是将其分解成更小的部分。
- 分离业务逻辑和表示逻辑. 这是一个很好的实践,将业务逻辑(即插件的工作方式)与 表示逻辑(即插件的外观)分开。 两个独立的逻辑更容易维护和替换。 例如,可以有两个不同的类:一个用于显示最终结果,另一个用于管理页面设置。
- 使用瞬态对象存储外部信息. 如果您通过 API 提供服务,最好存储这些信息,以便将来的查询可以更快地完成,并且减轻对您服务的负载。 可以使用 WordPress 瞬态对象 来存储数据一段时间。
- 记录可以用于调试的数据, 但需要满足两个条件:允许任何日志记录作为“可选”功能,并使用 WC_Logger 类。 用户可以在其系统状态页面上查看日志。 了解 如何将链接添加到您的扩展中的已记录数据。
- 使用 WP_DEBUG 模式打开,以便在屏幕上显示所有 PHP 警告。 这将标记诸如确保在检查值之前设置变量之类的问题。
- 将 质量洞察工具包 (QIT) 集成到您的开发工作流程中: QIT 允许您同时测试您的扩展程序与 PHP、WooCommerce 和 WordPress 的新版本以及其他活动扩展程序。 此外,该工具包还包括一个 命令行界面 (CLI) 工具,允许您运行和查看针对开发构建的测试。 这有助于在发布新版本之前捕获错误。
- 切勿在您的扩展程序中使用内部 WooCommerce 代码. 命名空间为
Automattic\WooCommerce\Internal的类以及带有@internal注释的代码仅供 WooCommerce 核心使用。 不保证内部代码的向后兼容性:它可能会在任何未来的版本中更改、重命名或删除。 在您的扩展程序中使用内部代码可能会导致在更新 WooCommerce 时出现问题。 请参阅 内部命名空间文档 了解详细信息。
WooCommerce 扩展的 GDPR 合规性指南
简介
《通用数据保护条例》(GDPR)已生效,赋予欧盟居民对其个人数据的更多权利。开发者必须确保 WooCommerce 扩展符合这些法规。
数据共享和收集
第三方数据共享
- 评估并记录任何第三方数据共享行为。
- 获取并管理用户对数据共享的同意。
- 在插件设置中链接到第三方隐私政策。
数据收集
- 列出您的插件收集的个人数据。
- 获取数据收集的同意,并管理用户偏好。
- 保护数据存储,并限制访问权限,仅授权给授权人员。
数据访问和存储
访问个人数据
- 明确您的插件从 WooCommerce 订单中访问哪些个人数据。
- 论证访问每种类型数据的必要性。
- 根据用户角色和权限控制对个人数据的访问。
存储个人数据
- 解释您的数据存储机制和位置。
- 对存储的个人数据进行加密保护。
- 定期进行安全审计。
个人数据处理
数据导出和删除钩子
- 集成数据导出和删除钩子,以符合用户请求。
- 创建一个用户友好的界面,用于数据管理请求。
拒绝数据删除
- 定义在拒绝数据删除的明确协议。
- 以透明的方式向用户传达这些协议。
前端和后端数据暴露
前端数据
- 尽量减少在网站前端显示的人员数据。
- 提供可配置的设置,根据用户状态控制数据的可见性。
REST API 端点中的数据
- 确保 REST API 端点是安全的,并且仅在必要时披露个人数据。
- 建立明确的权限,用于通过 API 访问个人数据。
隐私文档和数据管理
隐私政策文档
- 维护一份最新的隐私政策,详细说明您的插件如何处理数据。
- 在您的文档中包括浏览器存储方法和第三方数据共享。
数据清理
- 实施插件卸载以及删除订单/用户的的数据清理协议。
- 在适当的情况下,自动化个人数据删除流程。
结论
- 记录 GDPR 合规性措施,并使其对用户可用。
- 定期更新您的隐私政策,以使其与数据处理活动的变化保持一致。
WooCommerce 扩展的隐私标准
在线隐私和数据保护变得越来越重要,WooCommerce 扩展也不例外。本文档概述了 WooCommerce 扩展在隐私方面质量的关键指标,以及当前用于测试合规性的方法,以及开发者应遵循的标准,以确保用户信任和法律合规性。
隐私标准
为了保持高标准的隐私保护,WooCommerce 扩展的开发者应遵循以下原则:
隐私政策网页的存在
- 隐私政策应易于访问和理解。它必须清楚地描述扩展收集的数据类型、数据收集的目的、数据的处理和存储方式,以及用户对其数据的权利。
不允许未经授权的外部请求
- 扩展所需的所有资源应托管在插件文件夹/zip 文件中,除非有明确且合理的理由进行外部请求,并且这些请求应在隐私政策中披露。
- 未经授权或未披露的外部请求,尤其是那些可能在未经用户同意的情况下将用户数据暴露给第三方服务的请求,严格违反隐私标准。
GDPR 合规性
有关如何确保您的 WooCommerce 扩展符合《通用数据保护条例》(GDPR) 的指导,请参阅我们关于 GDPR 合规性 的详细文档。
结论
遵守隐私标准对于 WooCommerce 扩展开发者来说至关重要,这有助于建立与用户的信任,并确保符合法律要求。通过建立清晰的隐私政策并避免未经授权的外部请求,开发者可以展示他们对隐私和数据保护的承诺。定期测试和合规性检查将有助于维持这些标准,并有效地保护用户数据。
WooCommerce 扩展的支持和文档
有效的支持和全面的文档是任何 WooCommerce 扩展成功的基石。它们不仅能提升用户体验,还能促进更轻松的维护和开发。本文档概述了创建文档、提供支持和建立反馈机制的最佳实践。
创建有效的文档
优秀的文档是指导,帮助用户理解并充分利用您的扩展。它可以显著减少支持请求的数量,通过解答常见问题和解决典型问题。
良好文档的重要性
- 用户自主性: 允许用户独立解决问题。
- 减少支持负担: 全面的文档可以解答许多用户问题,减少直接支持的需求。
- 提高用户满意度: 当用户能够轻松找到信息时,他们对产品的满意度更高。
如何创建有效的文档
- 用户友好的语言: 使用清晰、简单的语言,使所有技能水平的用户都能理解。
- 全面的覆盖: 涵盖扩展的所有功能,包括设置、配置、故障排除和常见问题解答。
- 可访问性: 确保文档易于浏览,具有清晰的结构和搜索功能。
- 定期更新: 保持文档与扩展的最新版本同步。
文档标准
- 公共文档的存在: 确保用户可以访问基本的文档,其中包含有关扩展的重要信息。
- 公共文档的质量: 文档应清晰、简洁,避免使用技术术语。
- 面向开发者的文档: 为希望扩展或集成到您的扩展的开发人员提供详细的文档。
- 高级内部文档: 维护深入的文档,用于内部使用,涵盖复杂功能和开发人员笔记。
提供支持
提供及时有效的支持对于解决用户问题和维护良好的声誉至关重要。
提供支持的最佳实践
- 服务级别协议 (SLA): 建立明确的 SLA,用于响应时间,以管理用户期望。
- 知识渊博的员工: 确保您的团队接受过良好的培训,并且熟悉扩展和常见问题。
- 主动支持: 监控常见问题,并主动联系可能受到影响的用户。
支持标准
- 支持 - SLA: 定义一个 SLA,说明支持请求将如何快速得到确认和解决。
- 支持质量: 定期审查支持互动,以确保质量、准确性和帮助性。
反馈机制
反馈对于持续改进您的扩展和支持服务至关重要。
如何建立和利用反馈渠道
- 调查和反馈表单: 在您的说明文档网页上,实施支持后的调查和反馈表单。
- 社区论坛: 在社区论坛上与用户互动,让他们可以在那里分享反馈、提出问题并提供建议。
- 社交媒体和邮件: 鼓励用户通过社交媒体渠道和支持邮件提供反馈。
利用反馈进行改进
- 采取行动: 定期审查反馈,以识别扩展和支持服务中需要改进的领域。
- 更新文档: 使用反馈来填补说明文档中的空白,并澄清现有内容。
- 培训支持人员: 使用常见问题和反馈来培训您的支持人员,并改进他们的知识库。
结论
支持和文档是 WooCommerce 扩展的整体用户体验的关键组件。 通过投资高质量的文档、提供卓越的支持,并积极寻求和利用用户反馈,开发者可以提高用户满意度、减少支持工作量,并不断改进他们的扩展。
WooCommerce 扩展开发最佳实践
想创建一个插件来扩展 WooCommerce 吗? 您来对地方了。
WooCommerce 扩展与普通的 WordPress 插件相同。 更多信息,请访问 撰写插件。
您的 WooCommerce 扩展应该:
- 遵循所有 WordPress 插件的编码标准,以及 最佳实践指南,以确保在 WordPress 系统中与其他 WordPress 插件和谐共存。
- 具有单一的核心功能,并尽可能地使用 WooCommerce 的功能。
- 不做任何恶意、非法或不诚实的事情,例如,通过第三方系统插入垃圾链接或可执行代码,除非这些行为是服务的一部分或明确允许在服务的服务条款中。
- 不应破坏或覆盖核心 Marketplace 的连接,例如,扩展程序不能创建带有品牌名称的顶级菜单项,也不能引入自己的遥测数据。
- 遵循 WooCommerce 的 兼容性和互操作性指南。
商家每天都会使用 WooCommerce 扩展,他们应该在使用过程中获得统一且愉快的体验,而不会因为广告而干扰他们的 WP 管理界面或商店。
最佳实践
- 检查 WooCommerce 是否已启用. 大多数 WooCommerce 插件只有在 WooCommerce 已经启用时才需要运行。 了解如何检查 WooCommerce 是否已启用。
- 主插件文件应采用插件的名称. 例如:一个目录名为
plugin-name的插件,其主文件应命名为plugin-name.php。 - 文本域名应与您的插件目录名称匹配. 例如:一个目录名为
plugin-name的插件,其文本域名应为plugin-name。 请勿使用下划线。 - 国际化: 遵循 WordPress 开发者国际化指南。
- 本地化: 插件代码中的所有文本字符串应使用英语。 这是 WordPress 的默认语言环境,英语始终应该是第一种语言。 如果您的插件面向特定市场(例如西班牙或意大利),请在您的插件包中包含适用于这些语言的翻译文件。 了解更多信息,请查看 使用 Makepot 翻译您的插件。
- 遵循 WordPress PHP 指南. WordPress 有一套 指南,旨在保持所有 WordPress 代码的一致性和易读性。 这包括引号、缩进、花括号样式、简短的 PHP 标签、Yoda 条件、命名约定等等。 请仔细阅读这些指南。
- 尽量避免创建自定义数据库表. 尽可能使用 WordPress 文章类型、分类法 和 选项。 更多信息,请查看我们的 数据存储入门指南。
- 防止数据泄露,确保您没有提供直接访问 PHP 文件的途径。 了解如何操作。
- 所有插件都需要一个标准的 WordPress README 文件。 请参考 WordPress 插件 README 文件标准 中的示例。
- 所有插件都需要一个变更日志文件。 请参考 变更日志文档 中的示例,了解变更日志文件以及不同类型的变更日志条目。
- 遵循我们插件头部注释的约定. 请参考我们的 WordPress 插件头部注释示例,并遵循其中列出的约定,包括:
Author:、Author URI:、Developer:、Developer URI、WC requires at least:、WC tested up to:和Plugin URI:。 - 使其可扩展: 使用 WordPress 的动作和过滤器,允许进行修改/自定义。 如果您的插件生成前端输出,我们建议使用模板引擎,以便用户可以在其主题的 WooCommerce 文件夹中创建自定义模板文件,以覆盖插件的模板文件。 更多信息,请查看 Pippin 关于 使用动作和过滤器编写可扩展插件 的文章。
- 避免使用外部库. 通常不建议使用整个外部库,因为这可能会使产品存在安全漏洞。 如果绝对需要使用外部库,开发人员应仔细考虑所使用的代码,并承担代码的所有权和责任。 尽量只包含库中严格必要的部分,或者使用 WordPress 友好的版本,或者自行构建版本。 例如,如果需要使用文本编辑器,例如 TinyMCE,我们建议使用 WordPress 友好的版本 TinyMCE Advanced。
- 避免使用第三方系统: 允许从已记录的服务加载代码,但通信必须是安全的。 在插件中执行外部代码是不允许的。 禁止使用第三方 CDN 为与服务无关的 JavaScript 和 CSS 提供服务。 不应使用 iframe 连接管理页面。
- 删除未使用的代码. 使用版本控制时,没有理由留下注释掉的代码;它会让人感到不便。 删除它,如果需要,稍后可以重新添加。
- 使用注释 来描述您的代码的功能。 如果您有一个函数,该函数的作用是什么? 您的代码中应该为大多数甚至所有函数都添加注释。 某人/您可能需要修改插件,而注释对于此非常有用。 我们建议使用类似于 WooCommerce 的 PHP 文档块。
- 避免使用“上帝对象”. 上帝对象 是指那些知道或执行过多事情的对象。 面向对象编程的目的是将一个大问题分解成更小的部分。 当函数执行过多操作时,很难理解其逻辑,这会使修复错误变得更加困难。 不要使用大型函数,而是将其分解成更小的部分。
- 分离业务逻辑和表示逻辑. 这是一个很好的实践,将业务逻辑(即插件的工作方式)与 表示逻辑(即插件的外观)分开。 两个独立的逻辑更容易维护和替换。 例如,可以有两个不同的类:一个用于显示最终结果,另一个用于管理页面设置。
- 使用瞬态对象存储外部信息. 如果您通过 API 提供服务,最好存储这些信息,以便将来的查询可以更快地完成,并且减轻对您服务的负载。 可以使用 WordPress 瞬态对象 来存储数据一段时间。
- 记录可以用于调试的数据, 但需要满足两个条件:允许任何日志记录作为“可选”功能,并使用 WC_Logger 类。 用户可以在其系统状态页面上查看日志。 了解 如何将链接添加到您的扩展中的已记录数据。
- 使用 WP_DEBUG 模式打开,以便在屏幕上显示所有 PHP 警告。 这将标记诸如确保在检查值之前设置变量之类的问题。
- 将 质量洞察工具包 (QIT) 集成到您的开发工作流程中: QIT 允许您同时测试您的扩展程序与 PHP、WooCommerce 和 WordPress 的新版本以及其他活动扩展程序。 此外,该工具包还包括一个 命令行界面 (CLI) 工具,允许您运行和查看针对开发构建的测试。 这有助于在发布新版本之前捕获错误。
- 切勿在您的扩展程序中使用内部 WooCommerce 代码. 命名空间为
Automattic\WooCommerce\Internal的类以及带有@internal注释的代码仅供 WooCommerce 核心使用。 不保证内部代码的向后兼容性:它可能会在任何未来的版本中更改、重命名或删除。 在您的扩展程序中使用内部代码可能会导致在更新 WooCommerce 时出现问题。 请参阅 内部命名空间文档 了解详细信息。
如何添加操作和过滤器
像许多 WordPress 插件一样,WooCommerce 提供了各种操作和过滤器,允许开发者扩展和修改平台。
在撰写新代码或修改现有代码时,通常希望添加新的钩子,但务必谨慎对待。本文旨在提供关于此方面的总体指导。
我们通常允许、支持和鼓励的做法包括:
另一方面,我们不鼓励以下做法:
除了以上内容,我们通常遵循 WordPress 编码标准。 尤其是在钩子方面,这意味着遵循以下内容:
请注意,我们在这个指南中提供了示例代码,以帮助说明一些原则。 但是,为了保持简洁,我们通常省略不必要的细节,包括文档块(实际上,钩子应该始终附带文档块!)。
优先使用现有的钩子(或其他替代方案)
钩子会带来长期的义务:我们最不希望看到的是,开发者依赖于某个新的钩子,然后我们又将其移除。 然而,这可能会在重构包含钩子的代码时导致困难,有时会延迟有意义的更改,或者限制我们轻松实现更改而不影响向后兼容性的承诺。
因此,在合理的情况下,我们始终优先考虑使用现有的钩子或替代方法,而不是添加新的钩子。
添加生命周期钩子
生命周期钩子可以用于通知某个生命周期事件即将开始,或者已经结束。 这样的事件示例包括:
- 主要的产品循环
- 发送电子邮件
- 渲染模板
- 产品或订单状态的改变
一般来说,生命周期钩子:
- 总是成对出现(“before”和“after”)
- 始终是操作,而不是过滤器
- “before”钩子通常会提供带有参数数组的回调函数(如果存在)
- “after”钩子通常也会提供带有函数的返回值的回调函数(如果存在)
请注意,生命周期钩子主要用于允许其他系统观察,而不是用于修改结果。 当然,这并不妨碍函数的作者同时提供一个过滤器钩子,以实现该功能。
例如,我们认为“获取促销信息”的过程是“生命周期事件”,而不是函数本身:
function woocommerce_get_current_promotions( ...$args ) {
/* 任何初始准备,然后第一个生命周期钩子... */
do_action( 'woocommerce_before_get_current_promotions', $args );
/* ...执行实际操作,然后最终生命周期钩子... */
do_action( 'woocommerce_after_get_current_promotions', $result, $args );
/* ...返回结果,可选地通过过滤器... */
return apply_filters( 'woocommerce_get_current_promotions', $result, $args );
}
逃逸钩子
在某些情况下,支持函数的短路可能是有意义的。 我们称之为“逃逸钩子”,这可以作为一种覆盖代码的手段,当没有更好的方法时。
- 逃逸钩子始终是过滤器
- 它们应该始终提供
null作为初始的可过滤值 - 如果值被更改为非
null值,则函数应该提前退出,并返回该新值
为了类型安全,应注意确保,如果函数被短路,则返回类型必须与函数文档块中声明的函数签名和/或返回类型匹配。
示例:
function get_product_metrics( $args ): array {
$pre = apply_filters( 'pre_woocommerce_get_product_metrics', null, $args );
if ( $pre !== null ) {
return (array) $pre;
}
/* ...默认逻辑... */
return $metrics;
}
修改函数输入和输出 (全局渲染函数)
对于全局渲染或格式化函数(通常称为“模板标签”),如果难以实现更好的替代方案,可以为函数的参数和函数的返回值添加过滤器。
这应该谨慎使用,并且仅在必要时进行。 请记住,虽然这为其他组件提供了进行广泛自定义的机会,但它也可能导致其他组件出现问题,因为它们期望获得未修改的输出。
示例:
function woocommerce_format_sale_price( ...$args ): string {
/* 准备填充任何缺失的 $args 值... */
$args = (array) apply_filters( 'woocommerce_format_sale_price_args', $args );
/* ...实际工作以确定 $price 字符串... */
return (string) apply_filters( 'woocommerce_format_sale_price', $price, $args );
}
优先传递对象而不是 ID
某些操作或过滤器会提供一个对象 ID(例如,产品 ID),而其他操作或过滤器会提供实际的对象本身(例如,产品对象)。 为了保持一致性,建议传递对象。
示例:
function get_featured_product_for_current_customer( ) {
/* ...用于查找当前客户的特色产品的逻辑... */
return apply_filters(
'woocommerce_featured_product_for_current_customer',
$product, /* WC_Product */
$customer
);
}
将生命周期钩子与执行方法相关联
有时,可能会有多个路径导致相同的操作。 例如,订单可以通过 REST API、管理环境或前端进行更新。 此外,它也可能通过 AJAX 或通过常规请求进行。
但是,重要的是不要将高级过程的钩子与特定的执行路径相关联。 例如,当订单创建时触发的操作,不应该仅在管理环境中的 AJAX 请求中触发。
相反,请优先使用更通用的钩子,该钩子将传递有关执行方法的上下文信息给回调函数。
以下是我们要避免的示例:
/**
* 假想此函数仅在 AJAX 请求后调用
* (它本身可能使用 `wp_ajax_*` 操作进行挂钩)。
*/
function on_ajax_order_creation() {
/* 避免这样做! */
do_action( 'woocommerce_on_order_creation' );
}
使用过滤器作为功能标志
有时,人们可能会尝试使用过滤器作为一种功能标志,以启用或禁用某个功能。 应该避免这样做! 最好使用选项:
- 选项持久存储在数据库中。
- 选项已经是可过滤的(非常适合临时覆盖)。
以下是我们要避免的示例:
/* 避免这样做 */
$super_products_enabled = (bool) apply_filters( 'woocommerce_super_products_are_enabled', true );
/* 最好这样做 */
$super_products_enabled = get_option( 'woocommerce_super_products_are_enabled', 'no' ) === 'yes';
钩子的位置
过滤器不应放置在仅包含模板的操作中。如果模板中使用的某个值需要进行过滤,则相关的逻辑应移动到负责加载模板的函数或方法中,并将结果作为模板变量传递。
此外,建议不要将过滤器钩子放置在数据存储类中,因为这可能会降低这些组件的完整性:因为,根据设计,它们可以通过自定义实现进行替换,因此意外破坏这些自定义存储的风险更高。
钩子名称中的枚举值
虽然存在动态钩子名称的情况(其中钩子名称的一部分是使用变量创建的),但一个好的经验法则是,如果变量包含可能被认为是枚举值的,则应避免这种情况。
例如,当错误代码成为钩子名称的一部分时。
示例(我们希望避免的情况):
if ( is_wp_error( $result ) ) {
/* 避免这种情况 */
$error_code = $result->get_error_code();
do_action( "woocommerce_foo_bar_{$error_code}_problem", $intermediate_result );
/* 建议这样做 */
do_action( 'woocommerce_foo_bar_problem', $result );
}
避免这种情况的主要原因是,枚举集合中的值越多,开发者需要在他们的代码中包含的过滤器就越多。
摘要
本文档是关于钩子包含和放置的高级指南,而不是一个详尽的列表。有时可能会出现例外,并且可能存在我们遗漏的良好规则和方法:如果您有任何建议或改进的想法,请联系我们!
`changelog.txt` 格式
changelog.txt 文件
WooCommerce 扩展使用标准的日志格式。changelog.txt 文件是 WooCommerce 市场上的扩展的必需文件。
您的 changelog.txt 文件应如下所示:
*** WooCommerce 扩展名称 日志 ***
YYYY-MM-DD - 版本 1.1.0
* Added - 有用的新功能
* 另一个新功能
* 第三个新功能
* Fixed - 重要的 bug 修复
* Update - 与最新版本的兼容性
YYYY-MM-DD - 版本 1.0.1
* 修复了一个 bug
YYYY-MM-DD - 版本 1.0.0
* 初始发布
日志条目类型
为了展示产品更新中完成的不同类型的工作,请使用以下任何词语来表示每一行的更改类型:
- add
- added
- feature
- new
- developer
- dev
- tweak
- changed
- update
- delete
- remove
- fixed
- fix
日志嵌套
在特定条目类型下缩进的项目可以嵌套更多相同类型的更改,形成单级列表。
示例 changelog.txt
这是解析后的日志在 WooCommerce.com 上的模态框中的显示方式,其中每种条目类型都替换为图标。没有类型的日志条目会显示“其他”图标,而嵌套的条目则没有图标。

如何检查 WooCommerce 是否已激活
在为 WooCommerce 进行开发时,确保在您的代码运行之前 WooCommerce 已安装并处于激活状态至关重要。 这可以防止与缺少 WooCommerce 函数或类相关的错误。
有几种方法可以实现这一点。 第一种方法是在 woocommerce_loaded 动作上执行您的代码。 这种方法可以保证 WooCommerce 及其功能已完全加载并可供使用。 该动作大约在核心 plugins_loaded 动作触发的时间点触发。
add_action( 'woocommerce_loaded', 'prefix_woocommerce_loaded' );
function prefix_woocommerce_loaded() {
// 自定义代码在此处。 WooCommerce 已激活,并且所有插件都已加载...
}
注意: 在此阶段,WordPress 尚未初始化当前用户的相关数据。
另一种方法是在 woocommerce_init 动作上执行您的代码。 该动作在 WooCommerce 激活并初始化之后 立即执行。 该动作(以及 before_woocommerce_init 动作)在 WordPress 的 init 动作的上下文下触发,因此此时当前用户的相关数据已初始化。
add_action( 'woocommerce_init', 'prefix_woocommerce_init' );
function prefix_woocommerce_init() {
// 自定义代码在此处。 WooCommerce 已激活并初始化...
}
注意: before_woocommerce_init 钩子也是一个选项,它在 WooCommerce 初始化之前 运行。
使用上述钩子可以访问 WooCommerce 函数,从而可以进行进一步的条件检查。 例如,您可能需要验证 WooCommerce 的版本,以确保与您的代码兼容:
add_action( 'woocommerce_init', 'prefix_woocommerce_init' );
function prefix_woocommerce_init() {
// 仅当我们可以访问 8.7.0 或更高版本时才继续。
if ( version_compare( wc()->version, '8.7.0', '<' ) ) {
return;
}
// 自定义代码在此处。 WooCommerce 已激活并初始化...
}
根据您的开发需求选择合适的钩子,可以确保您的 WooCommerce 扩展或自定义功能能够平稳高效地运行。
WooCommerce 中的类
WooCommerce 中类的列表
要查看 WooCommerce 中类的列表,请参阅 WooCommerce 代码参考。
常用类
WooCommerce
主要的类是 woocommerce,它通过全局变量 $woocommerce 提供。该类负责 WooCommerce 的主要功能,初始化其他类,存储全局变量,并处理错误/成功消息。当创建 woocommerce 类时,它会初始化以下类:
WC_Query- 存储在$woocommerce->query中WC_Customer- 存储在$woocommerce->customer中WC_Shipping- 存储在$woocommerce->shipping中WC_Payment_Gateways- 存储在$woocommerce->payment_gateways中WC_Countries- 存储在$woocommerce->countries中
其他类会根据需要自动加载。
查看 WooCommerce 类代码参考,以获取此类中包含的所有方法的完整列表。
WC_Product
WooCommerce 包含多个产品类,负责加载和输出产品数据。您可以使用 PHP 加载它们:
$product = wc_get_product( $post->ID );
在循环中,这可能并不总是必要的,因为调用 the_post() 会自动将产品数据填充到全局 $product 变量中,如果该帖子是产品的话。
查看 WC_Product 代码参考,以获取此类中包含的所有方法的完整列表。
WC_Customer
客户类允许您获取有关当前客户的数据,例如:
global $woocommerce;
$customer_country = $woocommerce->customer->get_country();
查看 WC_Customer 代码参考,以获取此类中包含的所有方法的完整列表。
WC_Cart
购物车类加载并存储用户的购物车数据,例如,要获取购物车的小计,可以使用:
global $woocommerce;
$cart_subtotal = $woocommerce->cart->get_cart_subtotal();
查看 WC_Cart 代码参考,以获取此类中包含的所有方法的完整列表。
内部类 (请勿使用)
WooCommerce 包含一些不应由扩展程序使用的内部基础设施代码:
Automattic\WooCommerce\Internal\*: 命名空间中的所有类都是内部类。不保证向后兼容性:这些类可能会在 WooCommerce 的未来版本中发生更改、被重命名或被移除。- 带有
@internal注解的类: 同样,任何带有@internal注解的类、方法或钩子,都应该由扩展程序避免使用。
使用内部代码可能会导致您的扩展程序在 WooCommerce 更新时出现问题。 任何不属于上述定义的内部代码都是公共代码,通常可以安全使用。
有关更多详情,请参阅 内部命名空间文档。
WooCommerce 扩展的 WordPress 插件头部评论示例
这是一个 WordPress 插件头部评论。它用于向 WordPress 提供关于插件的元数据。
/**
* Plugin Name: WooCommerce 扩展
* Plugin URI: https://woocommerce.com/products/woocommerce-extension/
* Description: 您的扩展的描述文本。
* Version: 1.0.0
* Author: 您的姓名
* Author URI: http://yourdomain.com/
* Developer: 您的姓名
* Developer URI: http://yourdomain.com/
* Text Domain: woocommerce-extension
* Domain Path: /languages
*
* WC requires at least: 8.0
* WC tested up to: 8.3
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
* Woo: 12345:342928dfsfhsf8429842374wdf4234sfd
*/
以下是每一行应该包含的内容:
- Plugin Name: 您的插件名称。
- Plugin URI: 插件的主页或 WooCommerce.com 上的产品页面。
- Description: 插件的简短描述。
- Version: 插件的当前版本号。
- Author: 插件作者的姓名。
- Author URI: 作者的网站或个人资料页面。
- Developer: 如果开发者与作者不同,则填写开发者的姓名。
- Developer URI: 开发者的网站或个人资料页面。
- Text Domain: 文本域用于国际化。
- Domain Path: 域名路径用于显示 MO 文件所在的目录。
- WC requires at least: 插件正常工作所需的 WooCommerce 的最小版本。
- WC tested up to: 插件经过测试的最新版本的 WooCommerce。
- License: 插件的许可证。
- License URI: 详细说明许可证的 URL。
- Woo: 在 WooCommerce.com 上销售的插件的唯一标识符。在提交您的扩展或添加新版本时,我们会自动将其添加到您主文件的头部。 您无需手动添加,但可以选择在上传之前包含它。
此头部评论放置在主插件文件的顶部,以便 WordPress 可以读取它。
管理插件停用和卸载
简介
当商家停用或卸载您的插件时,您需要处理一些清理任务。本指南简要概述了您在定义插件的停用和卸载逻辑时,需要考虑的一些 WooCommerce 特定的事项。
移除计划的任务
如果您的插件使用 Action Scheduler 来排队任何后台任务,那么在您的插件被卸载或停用时,重要的是要取消这些任务的计划。
as_unschedule_all_actions( $hook, $args, $group );
您可以阅读更多关于使用 Action Scheduler 来管理后台处理的信息,请参考 Action Scheduler API 参考。
移除管理后台通知
如果您为商家创建了任何通知,您应该在您的插件被停用或,至少,在它被卸载时删除这些通知。
function my_great_extension_deactivate() {
ExampleNote::possibly_delete_note();
}
register_deactivation_hook( __FILE__, 'my_great_extension_deactivate' );
上面的示例假设您遵循了本指南推荐的模式,即创建将通知作为专用类,并包含 WooCommerce Admin 提供的 NoteTraits 特性。 这种方法为您的通知提供了内置的功能,简化了通知的操作,例如创建和删除。
移除管理后台任务
当您的插件被停用或卸载时,您应该采取措施来注销您的插件为商家创建的任何任务。
// 注销任务。
function my_extension_deactivate_task() {
remove_filter( 'woocommerce_get_registered_extended_tasks', 'my_extension_register_the_task', 10, 1 );
}
register_deactivation_hook( __FILE__, 'my_extension_deactivate_task' );
请记住,商家任务的管理采用一种混合方法,涉及 PHP 和 JavaScript,因此客户端注册仅在您的插件的 JavaScript 运行时发生。
注销导航
当您的插件停用和卸载时,您对 WooCommerce 导航所做的任何注册将自动处理。
WordPress 清理任务
根据您的插件在激活和运行时对底层 WordPress 环境所做的修改类型,您可能需要考虑一些额外的措施,以便在您的插件被停用或卸载时进行清理。 您可以阅读更多关于处理停用和卸载的信息,请参考 WordPress 插件开发者手册。
维护和更新 WooCommerce 扩展
维护和更新 WooCommerce 扩展对于确保其在不断发展的 WordPress 生态系统中保持兼容、安全和功能至关重要。本文档概述了确保易于维护的最佳实践,包括遵循更新频率和流程,以及进行手动更新检查。
确保易于维护
可维护的代码对于任何 WooCommerce 扩展的长期成功至关重要。它确保您的扩展可以轻松地进行更新、调试和扩展,无论是由您还是其他人在未来进行。
编写可维护代码的重要性
- 面向未来: 可维护的代码有助于适应未来的 WooCommerce 和 WordPress 更新。
- 协作: 方便团队成员共同开发扩展。
- 成本效益: 减少添加新功能或修复问题的所需时间和资源。
实现可维护性的策略
- 模块化代码: 将您的扩展分解为更小、更集中的模块或组件。
- 编码规范: 遵循 WordPress 编码规范,以确保一致性。
- 文档: 详细记录您的代码,以解释代码背后的“原因”,而不仅仅是“如何”使用它。
- 重构: 定期重构您的代码,以改进其结构,而不会改变外部行为。
更新频率和流程
保持您的扩展处于最新状态对于安全、兼容性和性能至关重要。定期更新还能向用户表明该扩展正在积极维护。
定期更新的最佳实践
- 计划更新: 制定定期更新计划(例如,每月),以包含错误修复、安全补丁和新功能。
- 版本控制: 使用版本控制系统(如 Git)来管理更改并高效协作。
- 兼容性检查: 在发布更新之前,请务必使用最新的 WordPress 和 WooCommerce 版本彻底测试您的扩展,以确保兼容性。
- 变更日志: 为每个更新维护清晰的变更日志,以告知用户有关新功能、修复和更改的信息。
推荐的更新频率
- 我们建议扩展至少每 30 天进行一次更新。 这种频率可确保扩展能够快速适应 WooCommerce、WordPress 或 PHP 的变化,并解决任何安全漏洞或错误。
手动更新检查
虽然像 WordPress 插件仓库这样的自动化更新系统提供了一种分发更新的方式,但开发人员还应制定一种手动跟踪和管理更新的流程。
开发者如何手动跟踪和管理更新
- 用户反馈: 监控论坛、支持请求和用户反馈,以发现可能需要更新的问题。
- 安全监控: 及时了解最新的安全漏洞,并确保您的扩展不受影响。
- 性能测试: 定期测试您的扩展的性能,并在更新中进行优化。
- 兼容性测试: 手动测试您的扩展与 WordPress 和 WooCommerce 的 beta 版本,以预先发现可能出现的兼容性问题。
结论
可维护性和定期更新是 WooCommerce 扩展成功的关键。通过撰写可维护的代码,遵循一致的更新流程,并积极监控扩展的性能和兼容性,开发者可以确保他们的产品在一段时间内对用户保持有价值和功能。
`wc_get_orders()` 和订单查询
wc_get_orders() 和 WC_Order_Query 提供了从数据库检索订单的标准方法,类似于 WordPress 的 get_posts() 和 WP_Query,但专门用于订单。
插件和主题的开发者应避免编写自定义的 WordPress 查询或直接的 SQL 语句,因为 WordPress 或 WooCommerce 数据库的更改可能会导致问题。 这些 API 提供了最佳实践,并且是获取 WooCommerce 中订单的未来兼容方式。
基本用法
示例
以下是一些示例:
// 获取名为 John 且于 2016 年付款的订单。
$orders = wc_get_orders(
array(
'billing_first_name' => 'John',
'date_paid' => '2016-01-01...2016-12-31',
)
);
// 获取 10 个最近的订单 ID。
$query = new WC_Order_Query(
array(
'limit' => 10,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
)
);
$orders = $query->get_orders();
// 获取电子邮件为 'woocommerce@woocommerce.com' 的客户的订单。
$query = new WC_Order_Query();
$query->set( 'customer', 'woocommerce@woocommerce.com' );
$orders = $query->get_orders();
请注意,wc_get_orders() 主要是 WC_Order_Query::get_orders() 的一个快捷方式。
最佳实践
- 避免直接的数据库查询,而应使用
wc_get_orders()。 - 如果您的代码需要支持旧版本,请在启用和禁用 HPOS 时进行彻底测试。
- 使用特定的参数来限制结果并提高性能。
- 对于大型结果集,请考虑使用
limit和offset进行分页。 - 在适当的情况下缓存结果。
- 对于复杂的过滤要求,请利用自 8.2 起在运行 HPOS 的站点上提供的新的查询参数
meta_query、field_query和date_query。
API 参考
| 方法 | 描述 |
|---|---|
wc_get_orders ( $args ) |
检索与查询 $args 匹配的订单。 |
WC_Order_Query::get_query_vars() |
获取当前查询对象上设置的所有查询变量的数组。 |
WC_Order_Query::get( string $key, mixed $default = '' ) |
获取查询变量的值,如果未设置查询变量,则返回默认值。 |
WC_Order_Query::set( string $key, mixed $value ) |
设置一个查询变量。 |
WC_Order_Query::get_orders() |
获取与当前查询变量匹配的所有订单。 |
以下是可与这些函数一起使用的查询参数/参数。
查询参数参考
General
| 参数 | 描述 |
|---|---|
| status | 接受一个字符串数组:默认情况下设置为 wc_get_order_statuses() 函数的键。 |
| type | 接受一个字符串:'shop_order'、'shop_order_refund' 或自定义订单类型。 |
| version | 接受一个字符串:订单创建时使用的 WooCommerce 版本号。 |
| created_via | 接受一个字符串:'checkout'、'rest-api' 或自定义创建方法别名。 |
| parent | 接受一个整数:父订单的帖子 ID。 |
| parent_exclude | 接受一个整数数组:排除具有父 ID 在数组中的订单。 |
| exclude | 接受一个整数数组:排除具有这些 ID 的订单。 |
| order | 接受一个字符串:'DESC' 或 'ASC'。与 'orderby' 配合使用。默认值:'DESC'。 |
| orderby | 接受一个字符串:'none'、'ID'、'name'、'type'、'rand'、'date'、'modified'。默认值:'date'。 |
| return | 返回类型。接受一个字符串:'ids' 或 'objects'。默认值:'objects'。 |
示例
// 获取最近修改的订单。
$args = array(
'orderby' => 'modified',
'order' => 'DESC',
);
$orders = wc_get_orders( $args );
// 获取一些随机订单。
$orders = wc_get_orders( array( 'orderby' => 'rand' ) );
// 仅返回订单 ID。
$orders = wc_get_orders( array( 'return' => 'ids' ) );
// 获取处理中和待处理的订单。
$args = array(
'status' => array( 'wc-processing', 'wc-on-hold' ),
);
$orders = wc_get_orders( $args );
// 获取过去 24 小时的退款订单。
$args = array(
'type' => 'shop_order_refund',
'date_created' => '>' . ( time() - DAY_IN_SECONDS ),
);
$orders = wc_get_orders( $args );
// 获取在 WooCommerce 2.6.14 版本创建并通过网站结账的订单。
$args = array(
'version' => '2.6.14',
'created_via' => 'checkout',
);
$orders = wc_get_orders( $args );
// 获取父帖子 ID 为 20 且不是订单 12 的订单。
$args = array(
'parent' => 20,
'exclude' => array( 12 ),
);
$orders = wc_get_orders( $args );
分页
| 参数 | 描述 |
|---|---|
| limit | 接受一个整数:要检索的最大结果数,或 -1 表示无限制。默认值:站点 'posts_per_page' 设置。 |
| paged | 接受一个整数:要检索的结果页码。如果使用了 'offset',则无效。 |
| offset | 接受一个整数:订单结果的偏移量。 |
| paginate | 接受一个布尔值:如果为真,则启用分页,否则禁用分页(默认:false)。如果启用,则修改返回结果,使其包含一个对象,该对象具有以下字段:orders(找到的订单数组)、total(找到的订单数量)和 max_num_pages(总页数)。 |
示例
// 获取最新的 3 个订单。
$orders = wc_get_orders( array( 'limit' => 3 ) );
// 前 3 个订单。
$args = array(
'limit' => 3,
'paged' => 1,
);
$page_1_orders = wc_get_orders( $args );
// 后 3 个订单。
$args = array(
'limit' => 3,
'paged' => 2,
);
$page_2_orders = wc_get_orders( $args );
// 获取包含关于结果的额外信息的订单。
$results = wc_get_orders( array( 'paginate' => true ) );
echo $results->total . " 个订单已找到\n";
echo '第 1 页,共 ' . $results->max_num_pages . " 页\n";
echo '第一个订单 ID 是: ' . $results->orders[0]->get_id() . "\n";
支付和金额
| 参数 | 描述 |
|---|---|
| currency | 接受一个字符串:订单中使用的货币。 |
| prices_include_tax | 接受一个字符串:'yes' 或 'no'。 |
| payment_method | 接受一个字符串:使用的支付方法的别名。 |
| payment_method_title | 接受一个字符串:使用的支付方法的完整标题。 |
| discount_total | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
| discount_tax | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
| shipping_total | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
| shipping_tax | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
| cart_tax | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
| total | 接受一个浮点数:用于匹配的未四舍五入的金额。 |
示例
// 获取使用 USD 支付的订单。
$orders = wc_get_orders( array( 'currency' => 'USD' ) );
// 获取使用支票支付的订单。
$orders = wc_get_orders( array( 'payment_method' => 'cheque' ) );
// 获取折扣总额为 20.00 的订单。
$orders = wc_get_orders( array( 'discount_total' => 20.00 ) );
客户
| 参数 | 描述 |
|---|---|
| customer | 接受一个字符串或一个整数:订单的账单电子邮件或客户 ID。 |
| customer_id | 接受一个整数:客户 ID。 |
| customer_ip_address | 接受字符串:用于匹配的值。 |
示例
// 获取客户电子邮件为 'woocommerce@woocommerce.com' 的订单。
$orders = wc_get_orders( array( 'customer' => 'woocommerce@woocommerce.com' ) );
// 获取客户 ID 为 12 的订单。
$orders = wc_get_orders( array( 'customer_id' => 12 ) );
账单和配送
| 参数 | 描述 |
|---|---|
| billing_first_name | 接受字符串:用于匹配的值。 |
| billing_last_name | 接受字符串:用于匹配的值。 |
| billing_company | 接受字符串:用于匹配的值。 |
| billing_address_1 | 接受字符串:用于匹配的值。 |
| billing_address_2 | 接受字符串:用于匹配的值。 |
| billing_city | 接受字符串:用于匹配的值。 |
| billing_state | 接受字符串:用于匹配的值。 |
| billing_postcode | 接受字符串:用于匹配的值。 |
| billing_country | 接受字符串:用于匹配的值。 |
| billing_email | 接受字符串:用于匹配的值。 |
| billing_phone | 接受字符串:用于匹配的值。 |
| shipping_first_name | 接受字符串:用于匹配的值。 |
| shipping_last_name | 接受字符串:用于匹配的值。 |
| shipping_company | 接受字符串:用于匹配的值。 |
| shipping_address_1 | 接受字符串:用于匹配的值。 |
| shipping_address_2 | 接受字符串:用于匹配的值。 |
| shipping_city | 接受字符串:用于匹配的值。 |
| shipping_state | 接受字符串:用于匹配的值。 |
| shipping_postcode | 接受字符串:用于匹配的值。 |
| shipping_country | 接受字符串:用于匹配的值。 |
示例
// 获取来自美国的订单。
$orders = wc_get_orders( array( 'billing_country' => 'US' ) );
// 获取名为 Bill Evans 的用户的订单。
$args = array(
'billing_first_name' => 'Bill',
'billing_last_name' => 'Evans',
);
$orders = wc_get_orders( $args );
日期
日期参数接收以下标准格式的值,允许更灵活的查询。
| 参数 | 描述 |
|---|---|
| date_created | 匹配订单创建日期。 接受标准格式的字符串。 |
| date_modified | 匹配订单修改日期。 接受标准格式的字符串。 |
| date_completed | 匹配订单完成日期。 接受标准格式的字符串。 |
| date_paid | 匹配订单支付日期。 接受标准格式的字符串。 |
标准格式
YYYY-MM-DD- 匹配该站点时区内某一天内的订单。>YYYY-MM-DD- 匹配该站点时区内该一天之后的订单。>=YYYY-MM-DD- 匹配该站点时区内该一天及其之后的所有订单。<YYYY-MM-DD- 匹配该站点时区内该一天之前的订单。<=YYYY-MM-DD- 匹配该站点时区内该一天及其之前的订单。YYYY-MM-DD...YYYY-MM-DD- 匹配该站点时区内某一天及其之间所有订单。TIMESTAMP- 匹配 UTC 时区内某一个秒的订单。>TIMESTAMP- 匹配 UTC 时区内该一个秒之后的订单。>=TIMESTAMP- 匹配 UTC 时区内该一个秒及其之后的所有订单。<TIMESTAMP- 匹配 UTC 时区内该一个秒之前的订单。<=TIMESTAMP- 匹配 UTC 时区内该一个秒及其之前的订单。TIMESTAMP...TIMESTAMP- 匹配 UTC 时区内某一个秒及其之间所有订单。
示例
// 获取 2016 年 2 月 12 日已支付的订单。
$orders = wc_get_orders( array( 'date_paid' => '2016-02-12' ) );
// 获取创建于过去一小时内的订单。
$args = array(
'date_created' => '<' . ( time() - HOUR_IN_SECONDS ),
);
$orders = wc_get_orders( $args );
// 获取 2017 年 5 月 16 日 21:46:17 UTC 到 2017 年 5 月 17 日 12:46:17 UTC 之间的已完成订单。
$args = array(
'date_completed' => '1494938777...1494971177',
);
$orders = wc_get_orders( $args );
元数据
| 参数 | 描述 |
|---|---|
| meta_query | 一个或多个包含键 key(元数据键)、value(可选,字符串或数组)以及可选的 type 和 compare 的数组。此参数类似于 WP_Query 的 meta_query,支持各种比较运算符以及通过 AND/OR 关系连接的查询级别。 |
有关更多详细信息和示例,请参阅 HPOS 订单查询 指南。
:::警告
只有当 HPOS 是配置的订单数据存储时(自 WooCommerce 8.2 以来为默认设置),才支持 meta_query。
在使用之前,请使用 OrderUtil::custom_orders_table_usage_is_enabled() 检查是否已启用。
:::
示例
// 具有元数据 'custom_field' 设置为 'some_value' 且元数据 'weight' 大于 '50' 的订单。
$orders = wc_get_orders(
array(
'meta_query' => array(
array(
'key' => 'custom_field',
'value' => 'some_value',
'compare' => '='
),
array(
'key' => 'weight',
'value' => '50',
'compare' => '>='
),
'relation' => 'AND'
)
)
);
订单字段
| 参数 | 描述 |
|---|---|
| field_query | 一个或多个包含键 field(任何订单属性)、value 以及可选的 type 和 compare 的数组。此参数类似于前面部分中描述的 meta_query 参数,支持各种比较运算符以及通过 AND/OR 关系连接的查询级别。 |
有关更多详情和示例,请参考 HPOS 订单查询 指南。
:::警告
field_query 的支持仅在 HPOS 作为配置的订单数据存储时可用(自 WooCommerce 8.2 以来为默认设置)。
在使用前,请使用 OrderUtil::custom_orders_table_usage_is_enabled() 检查是否已启用。
:::
示例
// 获取总额大于 100 或来自纽约市的订单。
$orders = wc_get_orders(
array(
'field_query' => array(
array(
'field' => 'total',
'value' => 100,
'compare' => '>'
),
array(
'field' => 'billing_city',
'value' => 'New York',
'compare' => '='
),
'relation' => 'OR'
)
)
);
高级日期查询
| 参数 | 描述 |
|---|---|
| date_query | 一个或多个包含键 column(订单日期:date_completed、date_created、date_updated 或 date_paid,可选地后跟 _gmt 表示 UTC 日期)、value 以及可选的 type 和 compare 的数组。此参数类似于 WP_Query 的 date_query,支持各种比较运算符以及通过 AND/OR 关系连接的查询级别。 |
有关更多详情和示例,请参考 HPOS 订单查询 指南。
:::警告
date_query 的支持仅在 HPOS 作为配置的订单数据存储时可用(自 WooCommerce 8.2 以来为默认设置)。
在使用前,请使用 OrderUtil::custom_orders_table_usage_is_enabled() 检查是否已启用。
:::
示例
// 示例:获取过去一个月内已支付且创建时间在中午之前的订单。
$orders = wc_get_orders(
array(
'date_query' => array(
'relation' => 'AND',
array(
'column' => 'date_created_gmt',
'hour' => 12,
'compare' => '<'
),
array(
'column' => 'date_paid_gmt',
'after' => '1 month ago',
),
),
)
);
添加对自定义参数的支持
开发者可以通过过滤生成的查询,为 wc_get_orders() 和 WC_Order_Query 添加对自定义参数的支持,从而扩展查询功能。
WooCommerce 当前支持两种订单存储机制:HPOS(默认)和旧版(使用 WordPress 帖子和元数据),每种机制都有自己的钩子,用于过滤生成的查询:
- (HPOS)
woocommerce_order_query_args用于将参数转换为现有参数,或者woocommerce_orders_table_query_clauses用于编写自己的 SQL。 - (旧版)
woocommerce_order_data_store_cpt_get_orders_query用于将参数转换为WP_Query参数。
/**
* 示例:处理自定义 'customvar' 查询变量,以获取具有 'customvar' 元数据的订单。
*/
use Automattic\WooCommerce\Utilities\OrderUtil;
// HPOS 版本。
function handle_custom_query_var_hpos( $query_args ) {
if ( ! empty( $query_args['customvar'] ) ) {
if ( ! isset( $query_args['meta_query'] ) ) {
$query_args['meta_query'] = array();
}
$query_args['meta_query'][] = array(
'key' => 'customvar',
'value' => esc_attr( $query_args['customvar'] ),
);
unset( $query_args['customvar'] );
}
return $query_args;
}
// 旧版版本。
function handle_custom_query_var_legacy( $query, $query_vars ) {
if ( ! empty( $query_vars['customvar'] ) ) {
$query['meta_query'][] = array(
'key' => 'customvar',
'value' => esc_attr( $query_vars['customvar'] ),
);
}
return $query;
}
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
// HPOS。
add_filter(
'woocommerce_order_query_args',
'handle_custom_query_var_hpos'
);
} else {
// 旧版支持。
add_filter(
'woocommerce_order_data_store_cpt_get_orders_query',
'handle_custom_query_var_legacy',
10,
2
);
}
用法:
$orders = wc_get_orders( array( 'customvar' => 'somevalue' ) );
`wc_get_products` 和产品查询
wc_get_products 和 WC_Product_Query 提供了获取产品的标准方法,这种方法安全可靠,并且不会因为未来 WooCommerce 版本的数据库更改而失效。构建自定义 WP_Queries 或数据库查询很可能会在未来版本的 WooCommerce 中导致您的代码失效,因为数据正在迁移到自定义表中以提高性能。 这是插件和主题开发者获取多个产品的最佳实践方法。 wc_get_products 和 WC_Product_Query 类似于 WordPress 的 get_posts 和 WP_Query。 就像它们一样,您需要传递一个参数数组,定义搜索的条件。
基本用法
示例
以下是一些示例:
// 获取在 2016 年创建的可下载产品。
$products = wc_get_products( array(
'downloadable' => true,
'date_created' => '2016-01-01...2016-12-31',
) );
// 获取最近的 10 个产品 ID,按日期降序排列。
$query = new WC_Product_Query( array(
'limit' => 10,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
) );
$products = $query->get_products();
// 获取包含特定 SKU 的产品。
// 支持部分匹配,因此这将获取 SKU 为 "PRDCT-1", "PRDCT-2" 等的产品。
$query = new WC_Product_Query();
$query->set( 'sku', 'PRDCT' );
$products = $query->get_products();
请注意,wc_get_products() 基本上是 WC_Product_Query::get_products() 的一个快捷方式。
API 参考
| 方法 | 描述 |
|---|---|
wc_get_products( $args ) |
获取与查询 $args 匹配的产品。 |
WC_Product_Query::get_query_vars() |
获取当前查询对象上设置的所有查询变量的数组。 |
WC_Product_Query::get( string $key, mixed $default = '' ) |
获取查询变量的值,如果查询变量未设置,则返回默认值。 |
WC_Product_Query::set( string $key, mixed $value ) |
将查询变量设置为一个值。 |
WC_Product_Query::get_products() |
获取与当前查询变量匹配的所有产品。 |
以下描述了可用于这些函数的查询参数/参数。
查询参数参考
General
| 参数 | 描述 |
|---|---|
| status | 接受一个字符串或字符串数组:一个或多个值,可以是 'draft', 'pending', 'private', 'publish',或者自定义的状态。 参见 ProductStatus 类的常量。 |
| type | 接受一个字符串或字符串数组:一个或多个值,可以是 'external', 'grouped', 'simple', 'variable',或者自定义的类型。 参见 ProductType 类的常量。 |
| include | 接受一个整数数组:仅包含 ID 在数组中的产品。 |
| exclude | 接受一个整数数组:排除 ID 在数组中的产品。 |
| parent | 接受一个整数:产品父级的文章 ID。 |
| parent_exclude | 接受一个整数数组:排除父级 ID 在数组中的产品。 |
| order | 接受一个字符串:'DESC' 或 'ASC'。 与 'orderby' 配合使用。 默认值:'DESC'。 |
| orderby | 接受一个字符串:'none', 'ID', 'name', 'type', 'rand', 'date', 'modified'。 默认值:'date'。 |
| return | 返回类型。 接受一个字符串:'ids' 或 'objects'。 默认值:'objects'。 |
示例
// 获取草稿状态的产品。
$products = wc_get_products( array( 'status' => 'draft' ) );
// 使用常量类获取状态。
$products = wc_get_products( array( 'status' => \Automattic\WooCommerce\Enums\ProductStatus::DRAFT ) );
// 获取外部产品。
$products = wc_get_products( array( 'type' => 'external' ) );
// 获取仅限于特定 ID 的外部产品。
$args = array(
'type' => 'external',
'include' => array( 134, 200, 210, 340 ),
);
$products = wc_get_products( $args );
// 获取不是当前产品的产品。
$products = wc_get_products( array( 'exclude' => array( $product->get_id() ) ) );
// 获取具有特定父级的产品。
$products = wc_get_products( array( 'parent' => 20 ) );
// 获取最近修改的产品。
$args = array(
'orderby' => 'modified',
'order' => 'DESC',
);
$products = wc_get_products( $args );
// 获取一些随机产品。
$products = wc_get_products( array( 'orderby' => 'rand' ) );
// 仅返回产品 ID。
$products = wc_get_products( array( 'return' => 'ids' ) );
分页
| 参数 | 描述 |
|---|---|
| limit | 接受一个整数:要检索的最大结果数量,或使用 -1 表示无限制。 默认值:站点 posts_per_page 设置。 |
| page | 接受一个整数:要检索的结果页码。 如果使用 'offset',则此参数无效。 |
| offset | 接受一个整数:产品结果的偏移量。 |
| paginate | 接受一个布尔值:如果设置为 true,则启用分页;如果设置为 false,则禁用分页。 默认值:false。 如果启用,则修改返回结果,使其包含以下字段:products(找到的产品数组)、total(找到的产品数量)和 max_num_pages(总页数)。 |
示例
// 获取最新的 3 个产品。
$products = wc_get_products( array( 'limit' => 3 ) );
// 获取前 3 个产品。
$args = array(
'limit' => 3,
'page' => 1,
);
$page_1_products = wc_get_products( $args );
// 获取第二组 3 个产品。
$args = array(
'limit' => 3,
'page' => 2,
);
$page_2_products = wc_get_products( $args );
// 获取包含结果额外信息的 3 个产品。
$results = wc_get_products( array( 'paginate' => true ) );
echo $results->total . " 个产品已找到\n";
echo '第 1 页,共 ' . $results->max_num_pages . " 页\n";
if ( count( $results->products ) > 0 ) {
echo '第一个产品的 ID 是: ' . $results->products[0]->get_id() . "\n";
}
// 获取从第二个到第五个最新的产品。
$args = array(
'limit' => 4,
'offset' => 1,
);
$products = wc_get_products( $args );
产品查找
| 参数 | 描述 |
|---|---|
| sku | 接受一个字符串:用于匹配的产品 SKU。 对 SKU 进行部分匹配。 |
| name | 接受一个字符串:用于匹配的产品名称(标题)。 区分大小写取决于 WordPress 帖子表的排序规则。 |
| tag | 接受一个数组:限制结果,仅显示分配了特定标签的产品,标签使用别名。 |
| product_tag_id | 接受一个整数或整数数组:限制结果,仅显示分配了特定标签的产品,标签使用 ID。 |
| category | 接受一个数组:限制结果,仅显示分配了特定分类的产品,分类使用别名。 |
| product_category_id | 接受一个整数或整数数组:限制结果,仅显示分配了特定分类的产品,分类使用 ID。 |
示例
// 获取 SKU 中包含 "PRDCT" 的产品(例如 PRDCT-1 和 PRDCT-2)。
$products = wc_get_products( array( 'sku' => 'PRDCT' ) );
// 获取名为 "Test Product" 的产品。
$products = wc_get_products( array( 'name' => 'Test Product' ) );
// 获取带有 "Excellent" 或 "Modern" 标签的产品。
$products = wc_get_products( array( 'tag' => array( 'excellent', 'modern' ) ) );
// 通过标签 ID 获取产品。
$products = wc_get_products( array( 'product_tag_id' => array( 17, 23 ) ) );
// 获取衬衫。
$products = wc_get_products( array( 'category' => array( 'shirts' ) ) );
// 通过分类 ID 获取产品。
$products = wc_get_products( array( 'product_category_id' => array( 17, 23 ) ) );
尺寸和价格
| 参数 | 描述 |
|---|---|
| weight | 接受一个浮点数:用于匹配的重量值。 |
| length | 接受一个浮点数:用于匹配的长度值。 |
| width | 接受一个浮点数:用于匹配的宽度值。 |
| height | 接受一个浮点数:用于匹配的高度值。 |
| price | 接受一个浮点数:用于匹配的当前价格。 |
| regular_price | 接受一个浮点数:用于匹配的常规价格。 |
| sale_price | 接受一个浮点数:用于匹配的促销价格。 |
| total_sales | 接受一个整数:获取销售数量为该值的产品。 |
示例
// 获取宽度为 5.5 个单位,长度为 10 个单位的产品。
$args = array(
'width' => 5.5,
'length' => 10,
);
$products = wc_get_products( $args );
// 获取当前价格为 9.99 的产品。
$products = wc_get_products( array( 'price' => 9.99 ) );
// 获取从未被购买过的产品。
$products = wc_get_products( array( 'total_sales' => 0 ) );
产品设置
| 参数 | 描述 |
|---|---|
| virtual | 接受一个布尔值:限制为虚拟产品。 |
| downloadable | 接受一个布尔值:限制为可下载产品。 |
| featured | 接受一个布尔值:限制为推荐产品。 |
| sold_individually | 接受一个布尔值:限制为单独销售的产品。 |
| manage_stock | 接受一个布尔值:限制为启用了库存管理的产品。 |
| reviews_allowed | 接受一个布尔值:限制为允许评论的产品。 |
| backorders | 接受一个字符串:'yes', 'no' 或 'notify'。 |
| visibility | 接受一个字符串:'visible', 'catalog', 'search' 或 'hidden'。 参见 CatalogVisibility 常量类。 |
| download_limit | 接受一个整数:下载限制,或 -1 表示无限制。 |
| download_expiry | 接受一个整数:下载有效期(天数),或 -1 表示无限制。 |
示例
// 获取允许下载但不允许评论的产品。
$args = array(
'downloadable' => true,
'reviews_allowed' => false,
);
$products = wc_get_products( $args );
// 获取允许延期交货的产品。
$products = wc_get_products( array( 'backorders' => 'yes' ) );
// 获取在目录中显示的产品。
$products = wc_get_products( array( 'visibility' => 'catalog' ) );
// 使用常量类进行可见性设置。
$products = wc_get_products( array( 'visibility' => \Automattic\WooCommerce\Enums\CatalogVisibility::CATALOG ) );
// 获取下载次数无限制的产品。
$products = wc_get_products( array( 'download_limit' => -1 ) );
库存与库存状态
| 参数 | 描述 |
|---|---|
| stock_quantity | 接受一个整数:产品在库存中的数量。 |
| stock_status | 接受一个字符串:'outofstock' (缺货), 'instock' (有库存), 或 'onbackorder' (延期交货)。 参见 ProductStockStatus 常量类。 |
示例
// 获取库存数量仅剩一个的产品。
$products = wc_get_products( array( 'stock_quantity' => 1 ) );
// 获取缺货的产品。
$products = wc_get_products( array( 'stock_status' => 'outofstock' ) );
// 使用常量类进行库存状态设置。
$products = wc_get_products( array( 'stock_status' => \Automattic\WooCommerce\Enums\ProductStockStatus::OUT_OF_STOCK ) );
税费与配送
| 参数 | 描述 |
|---|---|
| tax_status | 接受一个字符串:'taxable' (应税), 'shipping' (包含运费), 或 'none' (免税)。 参见 ProductTaxStatus 常量类。 |
| tax_class | 接受一个字符串:税类别名。 |
| shipping_class | 接受一个字符串或字符串数组:一个或多个配送类型别名。 |
示例
// 获取应税的产品。
$products = wc_get_products( array( 'tax_status' => 'taxable' ) );
// 使用常量类进行税费状态设置。
$products = wc_get_products( array( 'tax_status' => \Automattic\WooCommerce\Enums\ProductTaxStatus::TAXABLE ) );
// 获取属于 "Reduced Rate" 税类别的产品。
$products = wc_get_products( array( 'tax_class' => 'reduced-rate' ) );
// 获取属于 "Bulky" 配送类型的产品。
$products = wc_get_products( array( 'shipping_class' => 'bulky' ) );
评论与评分
| 参数 | 描述 |
|---|---|
| average_rating | 接受一个浮点数:平均评分。 |
| review_count | 接受一个整数:评论数量。 |
示例
// 获取所有评分均为 5 颗星的产品。
$products = wc_get_products( array( 'average_rating' => 5.0 ) );
// 获取有 1 条评论的产品。
$products = wc_get_products( array( 'review_count' => 1 ) );
日期
日期参数接收以下标准格式的值,以便进行更灵活的查询。
| 参数 | 描述 |
|---|---|
| date_created | 匹配产品创建日期。 接受标准格式的字符串。 |
| date_modified | 匹配产品修改日期。 接受标准格式的字符串。 |
| date_on_sale_from | 匹配促销开始日期。 接受标准格式的字符串。 |
| date_on_sale_to | 匹配促销结束日期。 接受标准格式的字符串。 |
标准格式
YYYY-MM-DD- 匹配站点时区内某一天。>YYYY-MM-DD- 匹配站点时区内某一天之后的产品。>=YYYY-MM-DD- 匹配站点时区内某一天及其之后的产品。<YYYY-MM-DD- 匹配站点时区内某一天之前的产品。<=YYYY-MM-DD- 匹配站点时区内某一天及其之前的产品。YYYY-MM-DD...YYYY-MM-DD- 匹配站点时区内某一天及其之间(包括两端)的产品。TIMESTAMP- 匹配 UTC 时区内某一个秒的产品。>TIMESTAMP- 匹配 UTC 时区内某一个秒之后的产品。>=TIMESTAMP- 匹配 UTC 时区内某一个秒及其之后的产品。<TIMESTAMP- 匹配 UTC 时区内某一个秒之前的产品。<=TIMESTAMP- 匹配 UTC 时区内某一个秒及其之前的产品。TIMESTAMP...TIMESTAMP- 匹配 UTC 时区内某一个秒及其之间(包括两端)的产品。
示例
// 获取在 2016 年创建的可下载产品。
$products = wc_get_products( array(
'downloadable' => true,
'date_created' => '2016-01-01...2016-12-31',
) );
添加对自定义参数的支持
可以在 wc_get_products() 或 WC_Product_Query 中添加对自定义参数的支持。 要实现此功能,需要过滤生成的查询。
/**
* 处理自定义的 'customvar' 查询变量,以获取具有 'customvar' 元数据的产品。
* @param array $query - WP_Query 的参数。
* @param array $query_vars - WC_Product_Query 的查询变量。
* @return array 修改后的 $query
*/
function handle_custom_query_var( $query, $query_vars ) {
if ( ! empty( $query_vars['customvar'] ) ) {
if ( ! isset( $query['meta_query'] ) ) {
$query['meta_query'] = array();
}
$query['meta_query'][] = array(
'key' => 'customvar',
'value' => sanitize_text_field( $query_vars['customvar'] ),
);
}
return $query;
}
add_filter( 'woocommerce_product_data_store_cpt_get_products_query', 'handle_custom_query_var', 10, 2 );
用法:
$products = wc_get_products( array( 'customvar' => 'somevalue' ) );
WooCommerce 插件 API 回调
概述
本 文档 提供了关于如何使用 WooCommerce 插件 API 来发起插件 操作,特别是对于默认情况下未初始化的 网关 和 类 的指南。
回调 网址 结构
在 WooCommerce 2.0 之前,使用:
https://example.com/?wc-api=CALLBACK
在 WooCommerce 2.0 或更高版本中,使用以下端点:
https://example.com/wc-api/CALLBACK/
行为
当 访问 回调 网址 时,WooCommerce 将:
- 如果
可用,则初始化CALLBACK类 - 触发
woocommerce_api_callback操作 退出WordPress
接入 API 回调
要接入回调,请在您的插件中添加一个 钩子:
add_action( 'woocommerce_api_callback', 'your_callback_handler_function' );
回调后的重定向
可以使用您的自定义 句柄 函数在 操作 执行完成后将用户 重定向。
管理插件停用和卸载
简介
当商家停用或卸载您的插件时,您需要处理一些清理任务。 本指南简要概述了您在定义插件的停用和卸载逻辑时,需要考虑的一些与 WooCommerce 相关的项目。
移除计划任务
如果您的插件使用 Action Scheduler 来排队任何后台任务,那么在您的插件被卸载或停用时,重要的是取消这些任务的计划。
as_unschedule_all_actions( $hook, $args, $group );
您可以在 Action Scheduler API 参考 中了解更多关于使用 Action Scheduler 管理后台处理的信息。
移除管理后台通知
如果您为商家创建了任何通知,您应该在您的插件被停用或,至少,在它被卸载时删除这些通知。
function my_great_extension_deactivate() {
ExampleNote::possibly_delete_note();
}
register_deactivation_hook( __FILE__, 'my_great_extension_deactivate' );
上面的示例假设您遵循了本指南推荐的模式,即创建将通知作为专用类,并包含 WooCommerce Admin 中提供的 NoteTraits 特性。 这种方法为您的通知提供了内置功能,简化了通知的操作,例如创建和删除。
移除管理后台任务
当您的插件被停用或卸载时,您应该注意取消注册您的插件为商家创建的任何任务。
// 取消注册任务。
function my_extension_deactivate_task() {
remove_filter( 'woocommerce_get_registered_extended_tasks', 'my_extension_register_the_task', 10, 1 );
}
register_deactivation_hook( __FILE__, 'my_extension_deactivate_task' );
请记住,商家任务的管理采用一种混合方法,涉及 PHP 和 JavaScript,因此客户端注册仅在您的插件的 JavaScript 运行时发生。
取消注册导航
当您的插件停用和卸载时,您对 WooCommerce 导航所做的任何注册将自动处理。
WordPress 清理任务
根据您的插件在激活和运行时对底层 WordPress 环境所做的修改类型,您可能需要考虑一些额外的措施,以便在您的插件被停用或卸载时进行清理。 您可以在 WordPress 插件开发者手册 中了解更多关于处理停用和卸载的信息。
如何将自定义产品类型添加到“添加产品”向导列表
简介
WooCommerce 允许 开发者 扩展产品类型向导列表,从而提供更具可定制性和吸引力的体验,尤其是在“添加产品”向导任务中。 本教程将指导您如何使用 experimental_woocommerce_tasklist_product_types JavaScript 过滤器,将自定义产品类型添加到您的 WooCommerce 商店。
前置条件
- 具备基本的 JavaScript 和 PHP 知识。
- 您的 WordPress 站点已 安装 WooCommerce 8.8 或更高版本。
第一步:添加 JavaScript 过滤器
要将新的产品类型添加到向导列表,我们将使用 @wordpress/hooks 包,特别是 addFilter 函数。 如果您不熟悉,@wordpress/hooks 允许您修改或扩展 WordPress 和 WooCommerce 生态系统中的功能,而无需修改核心代码。
首先,确保您已安装 @wordpress/hooks 包。 如果没有,您可以使用 npm 或 yarn 将其添加到您的项目中:
npm install @wordpress/hooks
或者:
yarn add @wordpress/hooks
接下来,将以下 JavaScript 代码添加到您的项目中。 此代码片段演示了如何将“自定义产品”类型添加到向导列表:
/**
* External dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { Icon, chevronRight } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import FolderMultipleIcon from 'gridicons/dist/folder-multiple';
addFilter(
'experimental_woocommerce_tasklist_product_types',
'custom-product',
(productTypes) => [
...productTypes,
{
key: 'custom-product',
title: __('Custom product', 'custom-product'),
content: __('Create an awesome custom product.', 'custom-product'),
before: <FolderMultipleIcon />,
after: <Icon icon={chevronRight} />,
onClick: () => {
}
},
]
);
此过滤器添加了一个名为“自定义产品”的新产品类型,并附带简短的描述以及标题前后的图标,以提供视觉吸引力。
第二步:可选 - 自定义 onClick 处理程序
默认情况下,如果未提供 onClick 处理程序,向导任务将使用默认的 CSV 模板处理程序。 要自定义此行为,您可以在产品类型对象中指定自己的 onClick 处理程序。
第三步:修改 CSV 模板路径(可选)
如果您希望为您的自定义产品类型使用不同的 CSV 模板,您可以使用 PHP 中的 woocommerce_product_template_csv_file_path 过滤器来修改模板路径。 以下是一个更改模板路径的示例:
add_filter('woocommerce_product_template_csv_file_path', function($path) {
// 在此处指定您的自定义模板路径
return $newPath;
});
结论
使用 WooCommerce,扩展产品类型引导列表非常简单,并且提供了显著的灵活性,可以自定义引导体验。 通过遵循本教程中概述的步骤,您可以增强您的 WooCommerce 商店,并使“添加产品”任务更贴合您的特定需求,提供更有帮助的信息。
如何创建自定义产品导览
简介
WooCommerce 允许开发者扩展或替换产品导览,从而提供更具定制化和吸引力的产品创建体验。本教程将指导您如何使用 experimental_woocommerce_admin_product_tour_steps JavaScript 过滤器,将自定义产品导览添加到您的 WooCommerce 商店。
这与自定义产品类型引导列表的能力相辅相成。
前置条件
- 具备基本的 JavaScript 和 PHP 知识。
- 您的 WordPress 站点已安装 WooCommerce 8.8 或更高版本。
添加 JavaScript 过滤器
要修改或创建产品导览,我们将使用 @wordpress/hooks 包,特别是 addFilter 函数。 如果您不熟悉,@wordpress/hooks 允许您修改或扩展 WordPress 和 WooCommerce 生态系统中的功能,而无需修改核心代码。
首先,确保您已安装 @wordpress/hooks 包。 如果没有,您可以使用 npm 或 yarn 将其添加到您的项目中:
npm install @wordpress/hooks
或者:
yarn add @wordpress/hooks
接下来,将以下 JavaScript 代码添加到您的项目中。 此代码片段演示了如何使用自定义导览替换整个产品导览:
/**
* External dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
addFilter(
experimental_woocommerce_admin_product_tour_steps,
'custom-product',
(tourSteps, tourType) => {
if ('custom-product' !== tourType) {
return tourSteps;
}
return [
{
referenceElements: {
desktop: '#title',// 突出显示的元素
},
focusElement: {
desktop: '#title',// 聚焦的表单元素
},
meta: {
name: 'product-name', // 步骤名称
heading: __( '产品名称', 'custom-product' ),
descriptions: {
desktop: __(
'在此处开始输入您的新产品名称。 这将是您的客户在您的商店中看到的内容。',
'custom-product'
),
},
},
},
];
}
);
此过滤器用于 custom-product 产品类型的整个产品导览。 通过使用内置的 JavaScript 数组操作函数,您还可以自定义默认导览(通过修改、添加或删除步骤)。
tourType 由 tutorial_type GET 参数设置。
结论
通过 WooCommerce,扩展和自定义产品导览非常简单,并提供了显著的灵活性,可以自定义入门体验。 通过遵循本教程中概述的步骤,您可以增强您的 WooCommerce 商店,并使“添加产品”导览更符合您的特定需求。
如何实现商家入职流程
简介
入职流程是商家用户体验的关键部分。它有助于帮助他们取得成功,并确保他们不仅正确使用您的扩展程序,而且还能充分利用它。作为开发人员,您可以利用一些特别有用的功能来帮助入职使用您扩展程序的商家:
- 设置任务
- 商店管理链接
- 管理员备注
快速开始
我们将使用 @woocommerce/create-woo-extension 来构建一个现代的 WordPress JavaScript 插件开发环境。该工具为与 WooCommerce 集成创建了一个完全可用的开发环境。
在这个示例中,我们将使用 add-task 变体来创建一个基本的入职扩展程序,以便我们可以在此基础上进行构建。
在您的 wp-content/plugins 目录中,运行以下命令来创建您的扩展程序:
npx @wordpress/create-block -t @woocommerce/create-woo-extension --variant=add-task my-extension-name
导航到新创建的文件夹并开始开发:
cd my-extension-name
npm run start
可选地,您可以使用 wp-env 来创建一个本地的 WordPress 环境:
npm -g i @wordpress/env
wp-env start
不要忘记前往 /wp-admin/plugins.php 并激活您的插件。
使用设置任务
设置任务会出现在 WooCommerce 管理员主屏幕上,并提示商家完成某些步骤以设置您的扩展程序。添加任务是一个两步过程,需要:
- 使用 PHP 注册任务(以及其 JavaScript)
- 使用 JavaScript 构建任务,设置其配置,并将它添加到任务列表中。
使用 PHP 注册任务
要将您的任务注册为扩展的任务列表项目,您需要首先创建一个新的 PHP 类,该类继承自 Task 类。 此类将定义您自定义任务的属性和行为。
<?php
/**
* 自定义任务示例。
*
*/
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
/**
* 自定义任务类。
*/
class MyTask extends Task {
/**
* 获取任务 ID。
*
* @return string
*/
public function get_id() {
return 'my-task';
}
/**
* 标题。
*
* @return string
*/
public function get_title() {
return __( 'My task', 'woocommerce' );
}
/**
* 内容。
*
* @return string
*/
public function get_content() {
return __( '在此处添加您的任务描述,以便在任务列表中显示。', 'woocommerce' );
}
/**
* 时间。
*
* @return string
*/
public function get_time() {
return __( '2 分钟', 'woocommerce' );
}
}
在定义了您的自定义任务类之后,通过在 TaskLists 类上调用 add_task 方法,将其添加到任务列表中。 请注意,您需要在 init 钩子之前或在 init 钩子中调用 add_task 方法,因为引导任务是在 init 钩子中注册的。
# 注册任务。
function register_custom_task() {
// 注册任务。
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskLists;
TaskLists::add_task(
'extended', // 任务列表 ID(例如,'extended' 表示“接下来要做的”。)
new MyCustomTask(
TaskLists::get_list( 'extended' ) // 获取任务列表对象。
)
);
}
// 将注册函数挂载到 'init' 动作。
add_action('init', 'register_custom_task');
TaskList 类表示一个任务列表。 它包含用于管理任务列表的属性和方法。 我们当前有三个预定义的任务列表:
setup: 默认任务列表extended: “接下来要做的”任务列表secret_tasklist: “秘密”任务列表,用于具有通过其他方式访问的任务。
使用 JavaScript 添加任务
除了在 PHP 中注册任务之外,您还需要使用 JavaScript 构建任务组件,设置其配置,并将它添加到任务列表中。 例如,一个简单任务的 JavaScript 文件可能如下所示:
import { createElement } from '@wordpress/element';
import {
WooOnboardingTask,
WooOnboardingTaskListItem,
} from '@woocommerce/onboarding';
import { registerPlugin } from '@wordpress/plugins';
const Task = ( { onComplete, task, query } ) => {
// 在此处实现您的任务 UI/功能。
return <div></div>;
};
registerPlugin( 'add-task-content', {
render: () => (
<WooOnboardingTask id="my-task">
{ ( { onComplete, query, task } ) => (
<Task onComplete={ onComplete } task={ task } query={ query } />
) }
</WooOnboardingTask>
),
} );
registerPlugin( 'add-task-list-item', {
scope: 'woocommerce-tasks',
render: () => (
<WooOnboardingTaskListItem id="my-task">
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
// 在默认任务项目周围添加一个自定义包装器。
<div
className="woocommerce-custom-tasklist-item"
style={ {
border: '1px solid red',
} }
>
<DefaultTaskItem />
</div>
) }
</WooOnboardingTaskListItem>
),
} );
在上面的示例中,该扩展程序执行了几个不同的操作。 让我们分解一下:
处理导入
首先,从外部依赖项导入任何函数、组件或其他实用程序。
import { createElement } from '@wordpress/element';
import {
WooOnboardingTask,
WooOnboardingTaskListItem,
} from '@woocommerce/onboarding';
import { registerPlugin } from '@wordpress/plugins';
创建组件
接下来,我们创建一个 功能组件,该组件返回我们的任务卡片。 我们在这里使用的混合 JavaScript/HTML 语法称为 JSX。 如果您不熟悉它,您可以 在 React 文档中阅读更多相关信息。
import { onboardingStore } from '@woocommerce/data';
import { useDispatch } from '@wordpress/data';
const Task = ( { onComplete, task } ) => {
const { actionTask } = useDispatch( onboardingStore );
const { isActioned } = task;
return (
<Card className="woocommerce-task-card">
<CardBody>
{ __(
"此任务的完成状态取决于是否已执行操作。 下方的操作按钮将执行此任务,而完成按钮将在任务列表中乐观地完成任务,并重定向回任务列表。 请注意,在此示例中,任务必须先执行操作才能持久化完成状态。",
'plugin-domain'
) }{ ' ' }
<br />
<br />
{ __( '任务执行状态:', 'plugin-domain' ) }{ ' ' }
{ isActioned ? '已执行' : '未执行' }
<br />
<br />
<div>
<button
onClick={ () => {
actionTask( 'my-task' );
} }
>
{ __( '执行任务', 'plugin-domain' ) }
</button>
<button onClick={ onComplete }>
{ __( '完成', 'plugin-domain' ) }
</button>
</div>
</CardBody>
</Card>
);
};
在上面的示例中,我们使用 Card 和 CardBody 组件来构建任务组件。 CardBody 内部的 div 使用 JavaScript 表达式 ({}) 嵌入一个三元运算符,该运算符使用组件的状态来确定是将任务显示为已完成或未完成。
注册插件以添加任务内容
接下来,我们使用 SlotFills 将 Task 组件注册为名为 "add-task-content" 的插件。 此插件将 Task 组件嵌套在 WooOnboardingTask 组件中,并传递必要的属性。 我们还将插件的范围指定为 "woocommerce-tasks",使其仅在 WooCommerce 的任务列表中有效。
registerPlugin( 'add-task-content', {
render: () => (
{ ( {
onComplete,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
query,
task,
} ) => }
),
scope: 'woocommerce-tasks',
} );
注册插件以自定义任务列表项目
最后,我们注册另一个名为 "my-task-list-item-plugin" 的插件。该插件用于自定义任务列表项目的外观。它还针对 WooCommerce 的任务列表,并将 DefaultTaskItem 组件包装在具有附加样式的自定义包装器中。
registerPlugin( 'my-task-list-item-plugin', {
scope: 'woocommerce-tasks',
render: () => (
<WooOnboardingTaskListItem id="my-task">
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
// 在默认任务项目周围添加一个自定义包装器。
<div
className="woocommerce-custom-tasklist-item"
style={ {
border: '1px solid red',
} }
>
<DefaultTaskItem />
</div>
) }
</WooOnboardingTaskListItem>
),
} );
总而言之,用于简单任务的 JavaScript 文件扩展并自定义了 WooCommerce 任务列表的功能,允许用户更好地管理任务并个性化任务列表项目的外观。
使用 JavaScript 注册任务
除了在 PHP 中注册任务之外,您还需要注册并加载包含您的任务组件及其配置的编译后的 JavaScript 文件。一种常见的方法是创建一个专用的注册函数,该函数挂接到 WordPress 中的 admin_enqueue_scripts 动作。以下是一个带有注释的示例,说明此注册可能的样子:
/**
* 注册脚本以填充前端的任务内容。
*/
function add_task_register_script() {
if (
! class_exists( 'Automattic\WooCommerce\Internal\Admin\Loader' ) ||
! \Automattic\WooCommerce\Admin\PageController::is_admin_or_embed_page()
) {
return;
}
$asset_file = require __DIR__ . '/dist/index.asset.php';
wp_register_script(
'add-task',
plugins_url( '/dist/index.js', __FILE__ ), // 任务注册 JS
$asset_file['dependencies'],
$asset_file['version'],
true
);
wp_enqueue_script( 'add-task' );
}
add_action( 'admin_enqueue_scripts', 'add_task_register_script' );
通过遵循这些步骤,您的自定义任务应该会出现在 WooCommerce 的引导任务列表中。
要查看一个完整的示例,了解如何将自定义任务作为 WordPress 插件添加,您可以查看 add-task 示例目录。
要了解更多关于任务列表的信息,您可以参考 任务列表文档。
使用商店管理链接
当商家完成所有入职任务列表中的项目时,WooCommerce 会将其替换为包含一系列实用商店管理链接的部分。由于扩展的可见性可能是一个挑战,因此此部分是突出扩展的关键功能并帮助商家导航到这些功能的好方法。
商店管理部分具有相对较窄的用途,因此该部分目前不支持外部链接。 相反,它旨在快速在 WooCommerce 中导航。
添加您自己的商店管理链接是一个简单的过程,涉及:
- 安装支持图标的依赖项
- 在您的 PHP 代码中注册一个管理脚本
- 通过 JavaScript 过滤器进行钩入,以提供您的链接对象
安装 Icons 包
商店管理链接使用 @wordpress/icons 包。 如果您的扩展尚未使用它,则需要将其添加到您扩展的依赖项列表中。
npm install @wordpress/icons --save
注册 JavaScript
将您的自定义链接添加到商店管理部分的代码将位于一个 JavaScript 文件中。 我们将在我们的 PHP 文件中向 WordPress 注册并加载该文件:
function custom_store_management_link() {
wp_enqueue_script(
'add-my-custom-link',
plugins_url( '/dist/add-my-custom-link.js', __FILE__ ),
array( 'wp-hooks' ),
10
);
}
add_action( 'admin_enqueue_scripts', 'custom_store_management_link' );
此调用的第一个参数是句柄,即 WordPress 将用于引用我们正在注册的脚本的名称。 第二个参数是脚本所在的 URL。
第三个参数是一个数组,表示脚本依赖项。 通过在数组中提供 wp-hooks 句柄,我们确保我们的脚本可以访问我们将使用的 addFilter 函数,该函数用于将我们的链接添加到 WooCommerce 的列表中。
第四个参数是优先级,它确定 WordPress 中 JavaScript 加载的顺序。 在我们的示例中,我们将优先级设置为 10。 重要的是,您的脚本在商店管理部分呈现之前运行。 考虑到这一点,请确保您的优先级值低于 15,以确保您的链接正确显示。
通过 JavaScript 提供您的链接
最后,在您上面注册的 JavaScript 文件中,钩入 woocommerce_admin_homescreen_quicklinks 过滤器,并以一个简单的 JavaScript 对象的形式提供您的任务。
import { megaphone } from '@wordpress/icons';
import { addFilter } from '@wordpress/hooks';
addFilter(
'woocommerce_admin_homescreen_quicklinks',
'my-extension',
( quickLinks ) => {
return [
...quickLinks,
{
title: 'My link',
href: 'link/to/something',
icon: megaphone,
},
];
}
);
使用管理提示
管理提示旨在显示关于您的 WooCommerce 商店、扩展、活动和成就的有用信息。 它们也适用于显示可以帮助您完成日常管理和优化商店的任务的信息。 一个好的通用规则是,将管理提示用于以下类型的信息:
- 及时性
- 相关性
- 实用性
考虑到这一点,您可能希望使用管理提示来庆祝商家已经达成的某个重要里程碑,或者提供有关如何使用特定功能或流程的更多指导。 另一方面,您不应使用管理提示来发送关于同一主题的重复消息,也不应向所有用户发送仅对商店****子集的商家相关的提示。 可以在管理提示中进行特定促销活动,但请勿滥用该系统。 请根据您的最佳判断,记住主屏幕的目的是突出商店最重要的可操作任务。
尽管管理提示是 WooCommerce 中新的基于 React 的界面体验的一部分,但它们可以通过标准的 PHP 界面提供给开发者。
使用管理提示的推荐方法是将您的提示封装在自己的类中,该类使用 WooCommerce 管理中包含的 NoteTraits 特性。 以下是一个简单的示例,说明其外观:
# 示例笔记提供器
该插件添加一条带有时间戳的笔记,显示该笔记添加的时间。
```php
<?php
/**
* Simple note provider
*
* Adds a note with a timestamp showing when the note was added.
*/
namespace My\Wonderfully\Namespaced\Extension\Area;
// Exit if this code is accessed outside of WordPress.
defined ( 'ABSPATH' ) || exit;
// Check for Admin Note support
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ||
! class_exists( 'Automattic\WooCommerce\Admin\Notes\NoteTraits' )) {
return;
}
// Make sure the WooCommerce Data Store is available
if ( ! class_exists( 'WC_Data_Store' ) ) {
return;
}
/**
* Example note class.
*/
class ExampleNote {
// Use the Note class to create Admin Note objects
use Automatic\WooCommerce\Admin\Notes\Note;
// Use the NoteTraits trait, which handles common note operations.
use Automatic\WooCommerce\Admin\Notes\NoteTraits;
// Provide a note name.
const NOTE_NAME = 'my-prefix-example-note';
public static function get_note() {
// Our welcome note will include information about when the extension
// was activated. This is just for demonstration. You might include
// other logic here depending on what data your note should contain.
$activated_time = current_time( 'timestamp', 0 );
$activated_time_formatted = date( 'F jS', $activated_time );
// Instantiate a new Note object
$note = new Automattic\WooCommerce\Admin\Notes\Note();
// Set our note's title.
$note->set_title( '开始使用' );
// Set our note's content.
$note->set_content(
sprintf(
'插件已于 %s 激活。', $activated_time_formatted
)
);
// In addition to content, notes also support structured content.
// You can use this property to re-localize notes on the fly, but
// that is just one use. You can store other data here too. This
// is backed by a longtext column in the 数据库.
$note->set_content_data( (object) array(
'getting_started' => true,
'activated' => $activated_time,
'activated_formatted' => $activated_time_formatted
) );
// Set the type of the note. Note types are defined as enum-style
// constants in the Note class. Available note types are:
// error, warning, update, info, marketing.
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
// Set the type of layout the note uses. Supported layout types are:
// 'plain', 'thumbnail'
$note->set_layout( 'plain' );
// Set the image for the note. This property renders as the src
// attribute for an img tag, so use a string here.
$note->set_image( '' );
// Set the note name and source. You should store your extension's
// name (别名) in the source property of the note. You can use
// the name property of the note to support multiple sub-types of
// notes. This also gives you a handy way of namespacing your notes.
$note->set_source( 'inbox-note-example');
$note->set_name( self::NOTE_NAME );
// Add action buttons to the note. A note can support 0, 1, or 2 actions.
// The first parameter is the action name, which can be used for event handling.
// The second parameter renders as the label for the button.
// The third parameter is an optional URL for actions that require navigation.
$note->add_action(
'settings', '打开设置', '?page=wc-settings&tab=general'
);
$note->add_action(
'learn_more', '了解更多', 'https://example.com'
);
return $note;
}
}
function my_great_extension_activate() {
// This uses the functionality from the NoteTraits trait to conditionally add your note if it passes all of the appropriate checks.
ExampleNote::possibly_add_note();
}
register_activation_hook( __FILE__, 'my_great_extension_activate' );
function my_great_extension_deactivate() {
// This uses the functionality from the NoteTraits trait to conditionally remove your note if it passes all of the appropriate checks.
ExampleNote::possibly_delete_note();
}
register_deactivation_hook( __FILE__, 'my_great_extension_deactivate' );
拆解
让我们分解上面的示例,以了解每个部分的作用。
命名空间和功能可用性检查
首先,我们进行一些基本的命名空间和功能可用性检查,并添加一个安全措施,以确保此文件仅在 WordPress 应用程序空间内执行。
namespace My\Wonderfully\Namespaced\Extension\Area;
defined ( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes') ||
! class_exists( 'Automattic\WooCommerce\Admin\Notes\NoteTraits') ) {
return;
}
if ( ! class_exists( 'WC_Data_Store' ) ) {
return;
}
使用 Note 和 NoteTraits 对象
接下来,我们定义一个简单的类,该类将作为我们通知的提供者。为了创建和管理通知对象,我们将从 WooCommerce Admin 导入 Note 和 NotesTraits 类。
class ExampleNote {
use Automatic\WooCommerce\Admin\Notes\Note;
use Automatic\WooCommerce\Admin\Notes\NoteTraits;
}
提供一个唯一的通知名称
在继续之前,创建一个名为 NOTE_NAME 的常量,并为其分配一个唯一的通知名称。NoteTraits 类使用此常量进行查询和通知操作。
const NOTE_NAME = 'my-prefix-example-note';
配置笔记的详情
在设置了笔记的名称后,您可以定义和配置您的笔记。 NoteTraits 类将在执行操作时调用 self::get_note(),因此您应该将笔记的实例化和配置封装在一个名为 get_note() 的静态函数中,该函数返回一个 Note 对象。
public static function get_note() {
// 我们将在此处填充逻辑,用于实例化一个 Note 对象
// 并设置其属性。
}
在我们的 get_note() 函数中,我们将处理任何用于收集 Note 可能需要的数据的逻辑。 我们的示例笔记将包含有关扩展何时激活的信息,因此这部分代码仅用于演示。 您可能在此处包含其他逻辑,具体取决于您的笔记应该包含哪些数据。
$activated_time = current_time( 'timestamp', 0);
$activated_time_formatted = date( 'F jS', $activated_time );
接下来,我们将实例化一个新的 Note 对象。
$note = new Note();
一旦我们拥有 Note 类的实例,我们就可以使用其 API 来设置其属性,首先是标题。
$note->set_title( 'Getting Started' );
然后,我们将使用上面收集的一些时间戳数据来设置笔记的内容。
$note->set_content(
sprintf(
'Extension activated on %s.', $activated_time_formatted
)
);
除了常规内容之外,笔记还支持使用 content_data 属性的结构化内容。 您可以使用此属性动态地重新定位笔记,但这只是一个用例。 您也可以在此处存储其他数据。 这由数据库中的一个 longtext 列支持。
$note->set_content_data( (object) array(
'getting_started' => true,
'activated' => $activated_time,
'activated_formatted' => $activated_time_formatted
) );
接下来,我们将设置笔记的 type 属性。 笔记类型定义为 Note 类中的枚举样式类常量。 可用的笔记类型包括 error、warning、update、info 和 marketing。 在选择笔记类型时,请注意,error 和 update 会导致笔记显示为商店警报,而不是在收件箱中。 最好避免使用这些类型的笔记,除非您绝对需要。
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
管理笔记还支持几种不同的布局。 您可以将 banner、plain 或 thumbnail 指定为布局。 如果您有兴趣查看不同的布局,请查看 此简单的插件,您可以安装它以进行实验。
我们将选择 plain 作为我们的布局,但它也是默认值,因此我们可以让此属性保持不变,效果相同。
$note->set_layout( 'plain' );
管理员通知
如果您想向您的管理员通知中添加图像,可以使用 set_image 函数指定它。 此属性最终会作为 img 标签的 src 属性呈现,因此请在此处使用一个 字符串。
$note->set_image( '' );
接下来,我们将设置管理员通知的 name 和 source 属性的 值。 最佳实践是,应将您的扩展程序的名称(即其 别名)存储在通知的 source 属性中。 您可以使用 name 属性来支持多种类型的通知。 这为您提供了一种方便的方法来命名您的通知,并在高层和底层进行管理。
$note->set_source( 'inbox-note-example');
$note->set_name( self::NOTE_NAME );
管理员通知可以支持 0 个、1 个或 2 个 操作(按钮)。 您可以使用这些 操作 来捕获触发异步过程的事件,或者帮助商家导航到特定的视图以完成某个步骤,或者仅仅提供指向外部网站的 链接,以获取更多 信息。 add_action() 函数最多可以接受三个 参数。 第一个参数是 操作 名称,可用于事件处理;第二个参数是 操作 按钮的 标签;第三个参数是可选的 URL,用于需要导航的 操作。
$note->add_action(
'settings', 'Open Settings', '?page=wc-settings&tab=general'
);
$note->add_action(
'learn_more', 'Learn More', 'https://example.com'
);
最后,请务必让 get_note() 函数返回配置的通知对象。
return $note;
添加和删除备注
要添加和删除备注,可以使用 NoteTraits 类中的辅助函数:possibly_add_note() 和其对应函数 possibly_delete_note()。 这些函数将处理与备注管理相关的重复逻辑,并且还会进行检查,以帮助您避免创建重复的备注。
我们的示例扩展通过将这些调用绑定到激活和停用钩子来实现,以简化操作。 虽然有很多事件您可能希望向商家的收件箱添加备注,但停用和卸载时删除备注是管理您的扩展生命周期的重要组成部分。
function my_great_extension_activate() {
ExampleNote::possibly_add_note();
}
register_activation_hook( __FILE__, 'my_great_extension_activate' );
function my_great_extension_deactivate() {
ExampleNote::possibly_delete_note();
}
register_deactivation_hook( __FILE__, 'my_great_extension_deactivate' );
集成即将推出的模式
本指南为第三方开发者和主机提供商提供示例,说明如何将他们的系统与 WooCommerce 的即将推出的模式集成。 更多详情,请阅读 开发者博客文章。有关站点可见性设置,请参阅 管理文档。
简介
WooCommerce 的即将推出的模式允许您在进行开发时,暂时将您的站点对公众隐藏。 本指南将向您展示如何将此功能与您的系统集成,并在站点可见性设置更改时清除服务器缓存,以及如何将即将推出的模式与其他插件同步。
前置条件
- 熟悉 PHP 和 WordPress 开发。
逐步说明
在站点可见性设置更改时清除服务器缓存
当站点的可见性设置发生更改时,可能需要清除服务器缓存,以应用更改并重新缓存面向客户的页面。 可以使用 update_option 钩子来实现此目的。
add_action( 'update_option_woocommerce_coming_soon', 'clear_server_cache', 10, 3 );
add_action( 'update_option_woocommerce_store_pages_only', 'clear_server_cache', 10, 3 );
function clear_server_cache( $old_value, $new_value, $option ) {
// 实现清除服务器缓存的逻辑。
if ( function_exists( 'your_cache_clear_function' ) ) {
your_cache_clear_function();
}
}
在模板更改时清除服务器缓存
默认情况下,即将推出的页面设置了 Cache-Control: max-age=60 头部。 此设置允许 CDN 和其他缓存机制将页面缓存 60 秒,在高效性能和合理的更新时间之间取得平衡。
当用户更改即将推出的模板时,建议清除任何缓存,以便在客户端缓存过期时,更改立即生效。
您可以使用 save_post_wp_template、save_post_wp_template_part 和 save_post_wp_global_styles 钩子来检测模板何时更新,并触发缓存清除。
add_action( 'save_post_wp_template', 'purge_cache_on_template_change', 10, 3 );
add_action( 'save_post_wp_template_part', 'purge_cache_on_template_change', 10, 3 );
add_action( 'save_post_wp_global_styles', 'purge_cache_on_template_change', 10, 3 );
function purge_cache_on_template_change( $post_id, $post, $update ) {
// 检查模板是否与即将推出的模式相关联。
if ( 'coming-soon' === $post->post_name ) {
// 实现清除服务器缓存的逻辑。
if ( function_exists( 'your_cache_clear_function' ) ) {
your_cache_clear_function();
}
}
}
与其他插件同步“即将推出”模式
“即将推出”模式可以通过插件或应用程序进行编程同步。以下是一些示例用例:
- 与“维护模式”插件集成。
- 与托管服务商的“即将推出”模式集成。
从 WooCommerce 触发
您可以使用以下示例来执行操作,例如在更新“即将推出”模式选项时设置插件的“状态”:
add_action( 'update_option_woocommerce_coming_soon', 'sync_coming_soon_to_other_plugins', 10, 3 );
function sync_coming_soon_to_other_plugins( $old_value, $new_value, $option ) {
$is_enabled = $new_value === 'yes';
// 实现同步“即将推出”状态的逻辑。
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
your_plugin_set_coming_soon( $is_enabled );
}
}
从其他插件触发
您可以使用以下示例,通过直接更新 woocommerce_coming_soon 选项,从另一个插件启用或禁用 WooCommerce “即将推出”模式:
function sync_coming_soon_from_other_plugins( $is_enabled ) {
// 检查用户权限。
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( '您没有足够的权限访问此页面。' );
}
// 设置“即将推出”模式。
if ( isset( $is_enabled ) ) {
update_option( 'woocommerce_coming_soon', $is_enabled ? 'yes' : 'no' );
}
}
双向同步与插件
如果需要双向同步,请使用以下示例,其中 update_option 不会递归调用 sync_coming_soon_from_other_plugins:
add_action( 'update_option_woocommerce_coming_soon', 'sync_coming_soon_to_other_plugins', 10, 3 );
function sync_coming_soon_to_other_plugins( $old_value, $new_value, $option ) {
$is_enabled = $new_value === 'yes';
// 实现同步“即将推出”状态的逻辑。
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
your_plugin_set_coming_soon( $is_enabled );
}
}
function sync_coming_soon_from_other_plugins( $is_enabled ) {
// 检查用户权限。
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( '您没有足够的权限访问此页面。' );
}
if ( isset( $is_enabled ) ) {
// 临时移除操作,以防止递归调用。
remove_action( 'update_option_woocommerce_coming_soon', 'sync_coming_soon_to_other_plugins', 10, 3 );
// 设置“即将推出”模式。
update_option( 'woocommerce_coming_soon', $is_enabled ? 'yes' : 'no' );
// 重新添加操作。
add_action( 'update_option_woocommerce_coming_soon', 'sync_coming_soon_to_other_plugins', 10, 3 );
}
}
使用选项覆盖实现单向绑定
我们还可以通过覆盖 woocommerce_coming_soon 选项,从另一个插件中以编程方式绑定“即将推出”选项。 这样做具有优势,因为它简化了状态管理,并防止了可能出现的同步问题。
在以下示例中,我们通过覆盖 woocommerce_coming_soon 选项,从另一个插件绑定“即将推出”选项。
add_filter( 'pre_option_woocommerce_coming_soon', 'override_option_woocommerce_coming_soon' );
function override_option_woocommerce_coming_soon( $current_value ) {
// 实现您的逻辑以同步“即将推出”状态。
if ( function_exists( 'your_plugin_is_coming_soon' ) ) {
return your_plugin_is_coming_soon() ? 'yes' : 'no';
}
return $current_value;
}
add_filter( 'pre_update_option_woocommerce_coming_soon', 'override_update_woocommerce_coming_soon', 10, 2 );
function override_update_woocommerce_coming_soon( $new_value, $old_value ) {
// 检查用户权限。
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( '您没有足够的权限访问此页面。' );
}
// 实现您的逻辑以同步“即将推出”状态。
if ( function_exists( 'your_plugin_set_coming_soon' ) ) {
your_plugin_set_coming_soon( $new_value === 'yes' );
}
}
自定义排除过滤器
开发者可以添加自定义排除规则,以绕过“即将推出”保护。 这对于排除某些情况非常有用,例如始终在特定 IP 地址上绕过“屏幕”,或者使特定的“网页”可用。
在所有页面禁用“即将推出”
如果存在其他功能与 WooCommerce 的“即将推出”模式类似,可能会导致意外冲突。 可以通过排除所有面向客户的“页面”来禁用“即将推出”模式。 以下是一个示例:
add_filter( 'woocommerce_coming_soon_exclude', function() {
return true;
}, 10 );
仅在特定页面上禁用“即将推出”
使用以下示例,根据“页面”的 ID 排除某个“页面”。 将 <page-id> 替换为您的“页面”标识符:
add_filter( 'woocommerce_coming_soon_exclude', function( $is_excluded ) {
if ( get_the_ID() === <page-id> ) {
return true;
}
return $is_excluded;
}, 10 );
自定义分享链接
以下示例显示了如何与自定义分享代码集成。 我们建议使用 Cookie 或其他存储机制来持久化访问,以便用户在浏览网站时保持访问状态:
add_filter( 'woocommerce_coming_soon_exclude', function( $exclude ) {
// 实现您的逻辑以获取和验证分享代码。
if ( function_exists( 'your_plugin_get_share_code' ) && function_exists( 'your_plugin_is_valid_share_code' ) ) {
$share_code = your_plugin_get_share_code();
if ( your_plugin_is_valid_share_code( $share_code ) ) {
return true;
}
}
return $exclude;
} );
扩展 "仅应用于商店网页" 设置
当使用 Apply to store pages only 设置时,您可能希望将自定义网页添加到商店网页列表中,这些网页将受到“即将推出”模式的限制。 您可以使用以下示例来添加自定义网页:
add_filter( 'woocommerce_store_pages', function( $pages ) {
$page = get_page_by_path( 'your-page-slug' );
if ( $page ) {
$pages[] = $page->ID;
}
return $pages;
} );
如何构建你的第一个扩展
本指南将教你如何使用 create-woo-extension 来创建 WooCommerce 扩展。与从头开始手动创建扩展相比,使用 create-woo-extension 具有诸多优势,包括:
需要编写的样板代码更少,需要手动设置的依赖项也更少。
诸如 Blocks 等现代特性默认支持,并且单元测试、代码检查和 Prettier IDE 配置已准备就绪。
在设置好你的扩展后,我们将向你展示如何使用 wp-env 快速搭建开发环境。
需求
在开始之前,你需要在你的设备上安装以下工具:
本指南也假设你熟悉命令行操作。
创建您的扩展
打开您的终端,并运行以下命令:
npx @wordpress/create-block -t @woocommerce/create-woo-extension my-extension-name
如果您希望设置自定义的扩展名称,可以将 my-extension-name 替换为任何别名。请注意,您的别名不能包含空格。
如果您看到类似 Need to install the following packages: @wordpress/create-block@4.34.0. Ok to proceed? 的提示,请按 Y 键。
当软件包完成您的扩展的生成后,使用以下命令进入扩展文件夹:
cd my-extension-name
然后,使用 npm install 安装扩展的依赖项,并使用 npm run build 进行构建。
恭喜!您已经成功创建了一个 WooCommerce 扩展!您的扩展将具有以下文件结构:
my-extension-nameblock.json- 包含用于在 WordPress 中注册您的自定义区块的元数据。了解更多详情。build- 您的扩展的构建版本,由npm run build生成。您不应直接修改此文件夹中的任何文件。composer.json- 包含您的 PHP 依赖项列表,由 Composer 引用。composer.lock- 此文件允许您控制何时以及如何更新这些依赖项。includes- 在 PHP 开发中,"includes" 文件夹的主要目的是存储可重用的代码或需要在项目多个部分中包含或引用的文件。 这是一个 PHP 开发者的约定。languages- 包含用于本地化的 POT 文件。my-extension-name.php- 您的插件的入口点,用于在 WordPress 中注册您的插件。node-modules- 帮助您构建应用程序的基础模块,并编写更结构化的代码。package.json- 被认为是 Node 项目的核心。它记录元数据,安装功能性依赖项,运行脚本,并定义应用程序的入口点。README.md- 您的应用程序的介绍和使用说明。 任何特殊说明、作者的更新以及关于应用程序的详细信息都可以在此处以文本形式编写。src- 保持根目录的整洁,并提供源代码和其他资源之间的清晰分隔。tests- 可以包含您应用程序的单元测试,并将它们与源代码文件分开。vendor- 包含项目依赖项和您未编写的第三方代码。webpack.config.js- webpack 是一个模块打包工具。 它的主要目的是将 JavaScript 文件打包以供在浏览器中使用。
设置开发环境
我们建议使用 wp-env 来搭建本地开发环境。您可以 在此处了解更多关于 wp-env 的信息。 如果您尚未在本地安装 wp-env,可以使用以下命令进行安装:
npm -g i @wordpress/env.
安装完 wp-env 后,并且仍然在您的 my-extension-name 文件夹中,运行 wp-env start 命令。 几秒钟后,一个测试 WordPress 站点,其中包含您的 WooCommerce 和您的扩展程序,将在 localhost:8888 上运行。
如果您没有为您的扩展程序设置自定义名称,您可以访问 wp-admin/admin.php?page=wc-admin&path=%2Fmy-extension-name 来查看由 /src/index.js 生成的 设置页面。 wp-env 的默认用户名/密码组合是 admin / password。
下一步
现在您已经搭建好了您的扩展程序,您可以开始添加一些功能了! 以下是一些您可以包含的简单功能:
参考
访问 NPM 上的 @woocommerce/create-woo-extension 以获取包的参考信息 查看 wp-env 的命令参考,以了解更多关于高级功能的信息
如何设计一个简单的扩展
简介
构建一个为商家和购物者提供一流体验的 WooCommerce 扩展,需要一种混合的开发方法,结合 PHP 和现代 JavaScript。 PHP 处理扩展的生命周期和服务器端操作,而现代 JavaScript 允许您塑造其用户界面的外观和行为。
主插件文件
您的扩展的主要 PHP 文件是一个引导文件。 它包含有关您的扩展的重要元数据,WordPress 和 WooCommerce 使用这些元数据进行各种生态系统集成过程,并且它作为您的扩展功能的主要入口点。 虽然没有对命名此文件有特定的规定,但使用插件名称的连字符版本是一种常见的最佳实践。(例如:my-extension.php)
声明扩展元数据
您的扩展的主要插件文件应包含一个头部注释,其中包含有关您的扩展的重要元数据。 WordPress 有一个 头部要求 列表,所有插件都必须遵守,但对于 WooCommerce 扩展,还有一些额外的考虑因素:
以下是一个在 WooCommerce Marketplace 中列出的扩展的头部内容示例。
/**
* Plugin Name: My Great Extension for WooCommerce
* Plugin URI: https://woocommerce.com/products/my-extension-name/
* Description: 您的扩展的描述文本。
* Version: 1.0.0
* Author: 您的姓名
* Author URI: http://yourdomain.com/
* Developer: 您的姓名
* Developer URI: http://yourdomain.com/
* Text Domain: my-extension-name
* Domain Path: /languages
* Requires Plugins: woocommerce
*
* Woo: 12345:342928dfsfhsf8429842374wdf4234sfd
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
预防数据泄露
作为最佳实践,您的扩展的 PHP 文件应该在顶部包含一个条件语句,用于检查 WordPress 的 ABSPATH 常量。如果该常量未定义,则脚本应退出。
defined( 'ABSPATH' ) || exit;
此检查可防止您的 PHP 文件通过直接的浏览器访问而被执行,而是仅允许它们在 WordPress 应用程序环境中执行。
管理扩展的生命周期
由于您的主要 PHP 文件是您的扩展与 WordPress 之间的主要连接点,因此您应该将其用作管理扩展生命周期的中心。从最基本层面来看,这意味着处理以下内容:
- 激活
- 执行
- 停用
从这三个广泛的生命周期领域开始,您可以进一步细分您的扩展的功能,以帮助保持良好的职责分离。
处理激活和停用
在 WooCommerce 扩展中,一种常见的模式是在您的主要 PHP 文件中创建专门的函数,用作激活和停用的钩子。然后,您使用适用的注册函数将这些钩子注册到 WordPress。这告诉 WordPress 在插件被激活或停用时调用该函数。请考虑以下示例:
function my_extension_activate() {
// 您的激活逻辑放在此处。
}
register_activation_hook( __FILE__, 'my_extension_activate' );
function my_extension_deactivate() {
// 您的停用逻辑放在此处。
}
register_deactivation_hook( __FILE__, 'my_extension_deactivate' );
保持职责分离
有许多方法可以组织您扩展中的代码。您可以在 WordPress 插件开发手册中找到有关最佳实践的良好概述。无论您使用哪种方法来组织您的代码,WordPress 的共享应用程序空间都要求您在构建时考虑到互操作性。有一些常见的原则可以帮助您优化您的扩展,并确保它与其他扩展相协调:
- 使用命名空间和前缀以避免与其他扩展发生冲突。
- 使用类来封装您的扩展的功能。
- 检查现有的声明、作业和实现。
核心扩展类
如上所述,使用类封装您扩展的不同部分的功能是一个重要的措施,这不仅有助于互操作性,而且还可以使您的代码更易于维护和调试。您的扩展可能有很多不同的类,每个类都承担着一部分功能。至少,您的扩展应该定义一个中心类,该类可以处理自身的一个实例的设置、初始化和管理。
实现单例模式
除非您有特定的理由在扩展运行时创建主类的多个实例,否则您应该确保在任何时候全局范围内只有一个实例存在。 实现此目的的常见方法是使用单例模式。 在 PHP 类中设置单例的方法有很多种。 以下是一个基本的单例示例,它还实现了上面提到的关于命名空间和预先声明检查的一些最佳实践:
if ( ! class_exists( 'My_Extension' ) ) :
/**
* My Extension 核心类
*/
class My_Extension {
/**
* 类的单个实例。
*/
protected static $_instance = null;
/**
* 构造函数。
*/
protected function __construct() {
// 初始化逻辑将放在此处。
}
/**
* 主扩展实例。
* 确保只加载一个扩展实例或可以加载一个实例。
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* 禁止克隆。
*/
public function __clone() {
// 覆盖此 PHP 函数以防止对您的实例进行不需要的复制。
// 实现您自己的错误处理或使用 `wc_doing_it_wrong()`
}
/**
* 禁止反序列化此类实例。
*/
public function __wakeup() {
// 覆盖此 PHP 函数以防止对您的实例进行不需要的复制。
// 实现您自己的错误处理或使用 `wc_doing_it_wrong()`
}
}
endif;
请注意,上面的示例类是设计为通过调用静态类方法 instance() 来进行实例化,该方法将返回类的现有实例,或者创建一个实例并将其返回。 为了完全防止不需要的实例化,还需要覆盖内置的魔术方法 __clone() 和 __wakeup()。 您可以在此处实现您自己的错误日志记录,或者使用类似于 _doing_it_wrong() 的函数,该函数可以为您处理错误日志记录。 您也可以在此处使用 WooCommerce 的包装函数 wc_doing_it_wrong()。 确保您的代码首先检查该函数是否存在。
构造函数
上面的示例包含一个空的构造函数,用于演示。然而,在实际的 WooCommerce 扩展中,此构造函数应该处理一些重要的任务:
-
检查是否已安装 WooCommerce 及其他相关的依赖项。
-
调用一个设置方法,该方法加载您的类所依赖的其他文件。
-
调用一个初始化方法,该方法使您的类及其依赖项准备就绪。
如果我们基于上面的示例,它可能如下所示:
protected function __construct() {
$this->includes();
$this->init();
// 您可能还可以在此处包含一些后续设置步骤,例如显示激活提示。
}
加载依赖项
上面的 includes() 函数是您加载其他类依赖项的地方,通常是通过 include 或 require 语句。管理和加载外部依赖项的一种常见方法是使用 Composer 的自动加载功能,但您也可以单独加载特定的文件。您可以在 Composer 的文档中了解更多关于如何自动加载外部依赖项的信息。以下是一个使用 Composer 和内部包含的设置方法的示例:
public function includes() {
$loader = include_once dirname( __FILE__ ) . '/' . 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php 缺失,请运行 `composer install`' );
}
require_once dirname( __FILE__ ) . '/' . 'includes/my-extension-functions.php';
}
初始化
上面的 init() 函数是您应该处理加载的类的任何设置的地方。在此步骤中,您通常会执行任何初始的注册,例如与相关的操作或过滤器进行注册。您还可以在此处注册并加载您的扩展的 JavaScript 和样式文件。
以下是您的初始化方法可能的样子示例:
private function init() {
// 设置缓存管理。
new My_Extension_Cache();
// 初始化 REST API。
new My_Extension_REST_API();
// 设置电子邮件管理。
new My_Extension_Email_Manager();
// 注册到 `some-action` 钩子
add_action( 'some-action', 'my-extension-function' );
}
您的核心类的初始化方法可能有许多不同的实现方式,这取决于您选择的扩展架构方式。这里重要的是,此函数作为处理您的扩展所需的所有初始注册和设置的中心点。
延迟初始化
我们之前使用 register_activation_hook() 设置的 WordPress 激活钩子,可能看起来是一个实例化扩展主类的理想位置,并且在某些情况下,它确实有效。但是,由于 WooCommerce 扩展通常是为 WooCommerce 构建的插件,因此为了正常运行,通常需要 WooCommerce 在其他插件加载之后再进行加载。因此,最好延迟实例化和初始化。
为此,不要将实例化挂接到扩展的激活钩子上,而是使用 WordPress 中的 plugins_loaded 动作来实例化扩展的核心类,并将它的单例添加到 $GLOBALS 数组中。
function my_extension_initialize() {
// 这是一个检查 WooCommerce 类是否存在的好地方
if ( ! class_exists( 'WooCommerce' ) ) {
// 您可以以多种方式处理这种情况,
// 但添加一个 WordPress 管理员通知通常是一个不错的策略。
return;
}
$GLOBALS['my_extension'] = My_Extension::instance();
}
add_action( 'plugins_loaded', 'my_extension_initialize', 10 );
在上面的示例中,WordPress 会在尝试实例化您的核心类之前,等待所有插件都加载完毕。 add_action() 中的第三个参数表示函数的优先级,它最终决定了挂接到 plugins_loaded 动作的函数的执行顺序。 在这里使用值 10,可确保其他与 WooCommerce 相关的功能在您的扩展被实例化之前运行。
处理执行
一旦您的扩展处于活动状态并已初始化,那么可能性就非常广泛。 这就是扩展中的“魔法”发生的地方,很大程度上取决于您来定义。 虽然实现特定功能超出了本指南的范围,但在您思考如何构建扩展的功能时,有一些最佳实践需要牢记。
-
保持事件驱动的思维方式。 使用您的扩展的商家和购物者将通过 Web 请求与 WooCommerce 交互,因此,将您的扩展与用户在 WooCommerce 中遵循的关键流程相关联可能很有帮助。
-
将业务逻辑和表示逻辑分开。 这可能很简单,例如,维护单独的类来处理后端处理和前端渲染。
-
尽可能,将功能分解为更小的部分,并将责任委托给专门的类,而不是构建臃肿的类和冗长的函数。
您可以在 WooCommerce 核心代码参考文档中找到类和钩子的详细文档,以及在 WooCommerce REST API 文档中找到 REST API 端点的其他文档。
处理停用
我们在主 PHP 文件中设置的 WordPress 停用钩子 (使用 register_deactivation_hook() 函数),是一个很好的地方,可以汇总任何需要在商家停用您的扩展时执行的清理操作。 除了您的扩展需要执行的任何与 WordPress 相关的停用任务之外,您还应该考虑与 WooCommerce 相关的清理,包括:
- 移除计划行动
- 移除管理员收件箱中的通知
- 移除管理员任务
卸载
虽然完全撤销您的扩展所创建的所有内容在商家停用它时是可能的,但这在大多数情况下并不建议也不实用。 相反,最好将这种行为保留用于卸载操作。
对于处理卸载,最好遵循 WordPress 插件手册中的指南。
整合所有内容
以下是一个非常简单的扩展的插件主文件的示例:
/**
* 插件名称: My Great Extension for WooCommerce
* 插件URI: https://woocommerce.com/products/my-extension-name/
* Description: 您的扩展的描述文本。
* Version: 1.0.0
* Author: Your Name
* Author URI: http://yourdomain.com/
* Developer: Your Name
* Developer URI: http://yourdomain.com/
* Text Domain: my-extension-name
* Domain Path: /languages
*
* Woo: 12345:342928dfsfhsf8429842374wdf4234sfd
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
defined( 'ABSPATH' ) || exit;
/**
* WordPress 的激活和反激活钩子
*/
function myPrefix_extension_activate() {
// 您的激活逻辑放在这里。
}
register_activation_hook( __FILE__, 'myPrefix_extension_activate' );
function myPrefix_extension_deactivate() {
// 您的反激活逻辑放在这里。
// 别忘了:
// 移除计划的操作
// 移除管理收件箱中的通知
// 移除管理任务
}
register_deactivation_hook( __FILE__, 'myPrefix_extension_deactivate' );
if ( ! class_exists( 'My_Extension' ) ) :
/**
* My Extension 核心类
*/
class My_Extension {
/**
* 类的单个实例。
*/
protected static $_instance = null;
/**
* 构造函数。
*/
protected function __construct() {
$this->includes();
$this->init();
}
/**
* 主扩展实例。
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* 复制是被禁止的。
*/
public function __clone() {
// 覆盖此 PHP 函数以防止对您的实例进行不需要的复制。
// 实现您自己的错误或使用 `wc_doing_it_wrong()`
}
/**
* 反序列化此类实例是被禁止的。
*/
public function __wakeup() {
// 覆盖此 PHP 函数以防止对您的实例进行不需要的复制。
// 实现您自己的错误或使用 `wc_doing_it_wrong()`
}
/**
* 用于加载依赖项的函数。
*/
private function includes() {
$loader = include_once dirname( __FILE__ ) . '/' . 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php 缺失,请运行 `composer install`' );
}
require_once dirname( __FILE__ ) . '/' . 'includes/my-extension-functions.php';
}
/**
* 用于设置所有内容并准备运行的函数。
*/
private function init() {
// 示例包括:
# 扩展初始化
// 设置缓存管理。
// new My_Extension_Cache();
// 初始化 REST API。
// new My_Extension_REST_API();
// 设置邮件管理。
// new My_Extension_Email_Manager();
// 注册到 `some-action` 钩子
// add_action('some-action', 'my-extension-function');
}
}
endif;
/**
* 用于延迟扩展的初始化,直到 WooCommerce 加载完毕。
*/
function my_extension_initialize() {
// 这是一个检查 WooCommerce 类是否存在的好地方。
if ( ! class_exists( 'WooCommerce' ) ) {
// 您可以用多种方式处理这种情况,
// 但在 WordPress 管理界面添加一个提示通常是一个不错的策略。
return;
}
$GLOBALS['my_extension'] = My_Extension::instance();
}
add_action( 'plugins_loaded', 'my_extension_initialize', 10 );
如何向设置选项卡添加一个部分
当您为 WooCommerce 构建一个需要某种设置的扩展程序时,重要的是要问自己:这些设置应该放在哪里? 如果您的扩展程序只有几个简单的设置,您真的需要为此创建一个新的选项卡吗? 最有可能的答案是“不”。
何时创建部分
假设我们有一个扩展程序,它为单个产品页面添加一个滑块。 此扩展程序只有几个选项:
- 自动插入到单个产品页面(复选框)
- 滑块标题(文本字段)
这只有两个选项,并且与 产品 密切相关。 我们可以很容易地将它们添加到核心 WooCommerce 产品设置(WooCommerce > 设置 > 产品),但这对于用户来说可能不够友好。 用户最初可能不知道在哪里查找,因此他们必须扫描所有产品选项,并且很难/无法直接链接这些选项。 幸运的是,从 WooCommerce 2.2.2 开始,有一个新的过滤器,允许您在核心设置选项卡下添加一个新的 部分。
如何创建部分
我们将通过单独的函数来演示如何操作,但您应该创建一个类来存储所有设置方法。
首先,您需要添加该部分,这可以通过钩入 woocommerce_get_sections_products 过滤器来实现:
/**
* 在产品选项卡下创建部分
*/
add_filter( 'woocommerce_get_sections_products', 'wcslider_add_section' );
function wcslider_add_section( $sections ) {
$sections['wcslider'] = __( 'WC Slider', 'text-domain' );
return $sections;
}
wc-create-section-beneath-products.php
请确保将 wcslider 部分更改为适合您扩展程序的名称/文本域。 woocommerce_get_sections_products 过滤器的重要部分是,最后的 products 表示您想要添加部分的选项卡。 如果您想将一个新选项卡添加到帐户部分,您应该钩入 woocommerce_get_sections_accounts 过滤器。
如何向一个部分添加设置
现在你已经有了标签,你需要过滤 woocommerce_get_sections_products 的输出(或类似的函数)。 你应该像往常一样使用 WooCommerce 设置 API 添加设置,但在将设置添加到标签的设置数组之前,请检查当前的 %s。 例如,让我们将上面讨论的示例设置添加到我们刚刚创建的 wcslider 部分:
/**
* 向之前创建的特定部分添加设置
*/
add_filter( 'woocommerce_get_settings_products', 'wcslider_all_settings', 10, 2 );
function wcslider_all_settings( $settings, $current_section ) {
/**
* 检查当前的 %s 是否是我们想要的
**/
if ( $current_section == 'wcslider' ) {
$settings_slider = array();
// 向设置中添加标题
$settings_slider[] = array( 'name' => __( 'WC Slider Settings', 'text-domain' ), 'type' => 'title', 'desc' => __( '以下选项用于配置 WC Slider', 'text-domain' ), 'id' => 'wcslider' );
// 添加第一个复选框选项
$settings_slider[] = array(
'name' => __( '自动插入到单个产品页面', 'text-domain' ),
'desc_tip' => __( '这将自动将您的幻灯片插入到单个产品页面', 'text-domain' ),
'id' => 'wcslider_auto_insert',
'type' => 'checkbox',
'css' => 'min-width:300px;',
'desc' => __( '启用自动插入', 'text-domain' ),
);
// 添加第二个文本字段选项
$settings_slider[] = array(
'name' => __( '幻灯片标题', 'text-domain' ),
'desc_tip' => __( '这将为您的幻灯片添加一个标题', 'text-domain' ),
'id' => 'wcslider_title',
'type' => 'text',
'desc' => __( '您可以添加任何您想要的标题,通过此选项添加到您的幻灯片!', 'text-domain' ),
);
$settings_slider[] = array( 'type' => 'sectionend', 'id' => 'wcslider' );
return $settings_slider;
/**
* 如果不是,则返回标准的设置
**/
} else {
return $settings;
}
}
我们正在钩入相同的 woocommerce_get_settings_products 过滤器,但这次我们检查 $current_section 是否与我们之前定义的自定义 %s(wcslider)匹配,然后再添加我们的新设置。
使用新的设置
现在,您可以像使用任何其他 WordPress / WooCommerce 设置一样,通过 [**get_option**](http://codex.wordpress.org/Function_Reference/get_option) 函数和已定义的设置 ID 来使用您新创建的设置。 例如,要使用之前创建的 wcslider_auto_insert 选项,只需使用以下代码:get_option( 'wcslider_auto_insert' )
结论
在为 WooCommerce 创建扩展程序时,在创建设置之前,请考虑您的设置应该放置在何处。 构建一个有用的产品的关键是使其易于最终用户使用,因此适当的设置位置至关重要。 要获取有关向 WooCommerce 添加设置的更多特定信息,请查看 Settings API 文档。
WooCommerce 邮件编辑器集成指南
本指南展示了扩展程序如何添加自定义邮件通知,并与 WooCommerce 邮件编辑器集成。 注意: WooCommerce 邮件编辑器目前处于 alpha 阶段。要启用它,请转到 WooCommerce > 设置 > 高级 > 功能,并启用 阻止邮件编辑器 (alpha)。
快速开始
- 扩展
WC_Email– 通过继承核心 WooCommerce 邮件类,为您的通知创建一个自定义邮件类。 - 通过
woocommerce_email_classes注册 – 将您的新邮件类添加到 WooCommerce,以便它出现在管理员邮件设置中。 - 通过块编辑器注册邮件 – 通过将您的邮件 ID 注册到
woocommerce_transactional_emails_for_block_editor过滤器,以启用块编辑器支持。 - 创建块模板 – 设计一个基于块的模板,以确保您的邮件与 WooCommerce 邮件编辑器无缝协作。
- 设置触发器 – 定义何时以及在什么条件下发送您的自定义邮件(例如,在特定用户操作或事件发生后)。
1. 创建邮件类
继承 WC_Email 并实现所需的 方法:
class YourPlugin_Custom_Email extends WC_Email {
public function __construct() {
$this->id = 'your_plugin_custom_email';
$this->title = __( 'Custom Email', 'your-plugin' );
$this->customer_email = true;
$this->email_group = 'your-plugin';
$this->template_html = 'emails/your-custom-email.php';
$this->template_plain = 'emails/plain/your-custom-email.php';
$this->template_base = plugin_dir_path( __FILE__ ) . 'templates/';
parent::__construct();
}
public function get_default_subject() {
return __( 'Your custom email subject', 'your-plugin' );
}
public function get_default_heading() {
return __( 'Your custom email heading', 'your-plugin' );
}
public function trigger( $order_id ) {
$this->setup_locale();
if ( $order_id ) {
$order = wc_get_order( $order_id );
$this->object = $order;
$this->recipient = $order->get_billing_email();
}
if ( $this->is_enabled() && $this->get_recipient() ) {
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
$this->restore_locale();
}
public function get_content_html() {
return wc_get_template_html( $this->template_html, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this,
) );
}
public function get_content_plain() {
return wc_get_template_html( $this->template_plain, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => true,
'email' => $this,
) );
}
}
2. 注册邮件
将您的邮件添加到 WooCommerce:
// 将自定义邮件类添加到 WooCommerce 邮件列表中。
function your_plugin_add_email_class( $email_classes ) {
$email_classes['YourPlugin_Custom_Email'] = new YourPlugin_Custom_Email();
return $email_classes;
}
add_filter( 'woocommerce_email_classes', 'your_plugin_add_email_class' );
// 添加自定义邮件组。 只有当 WC_Email 类上未设置 email_group 时才需要此操作。
function your_plugin_add_email_group( $email_groups ) {
$email_groups['your-plugin'] = __( 'Your Plugin', 'your-plugin' );
return $email_groups;
}
add_filter( 'woocommerce_email_groups', 'your_plugin_add_email_group' );
3. 在块编辑器中注册电子邮件
第三方扩展需要明确地将他们的电子邮件纳入块编辑器支持。 这通过将您的电子邮件 ID 注册到 woocommerce_transactional_emails_for_block_editor 过滤器来实现:
/**
* 注册用于块编辑器的自定义事务性电子邮件。
*
* @param array $emails 电子邮件 ID 数组。
* @return array 修改后的电子邮件 ID 数组。
*/
function your_plugin_register_transactional_emails_for_block_editor( $emails ) {
$emails[] = 'your_plugin_custom_email';
return $emails;
}
add_filter( 'woocommerce_transactional_emails_for_block_editor', 'your_plugin_register_transactional_emails_for_block_editor' );
重要: 如果缺少此步骤,您的电子邮件可能仍然出现在电子邮件列表中,但它将不会使用电子邮件编辑器,因为第三方开发者需要明确选择。
注意: 对于第三方扩展,除非您使用 woocommerce_transactional_emails_for_block_editor 过滤器进行选择,否则 WooCommerce 不会创建电子邮件帖子。
开发提示: WooCommerce 会使用一个瞬态缓存电子邮件帖子生成。 在测试或开发时,删除瞬态 wc_email_editor_initial_templates_generated 以强制重新生成帖子。
自定义电子邮件模板帖子生成
您可以在创建电子邮件模板帖子之前,使用 woocommerce_email_content_post_data 过滤器修改电子邮件模板帖子数据。 这允许您在模板生成期间自定义帖子标题、内容、元数据或任何其他帖子数据。
过滤器详情:
| 属性 | 值 |
|---|---|
| 钩子名称 | woocommerce_email_content_post_data |
| 自版本 | 10.5.0 |
| 参数 | $post_data (array), $email_type (string), $email_data (\WC_Email) |
| 返回值 | array |
参数:
$post_data(array) – 将传递给wp_insert_post()的帖子数据数组。 包含键,例如post_type、post_status、post_title、post_content、post_excerpt、post_name和meta_input。$email_type(string) – 电子邮件类型标识符(例如,'customer_processing_order')。$email_data(\WC_Email) – WooCommerce 电子邮件对象。
返回值:
返回修改后的帖子数据数组。 此数组将用于创建电子邮件模板帖子。
示例:修改电子邮件模板文章数据
/**
* 在生成过程中自定义电子邮件模板文章数据。
*
* @param array $post_data 文章数据数组。
* @param string $email_type 电子邮件类型标识符。
* @param \WC_Email $email_data WooCommerce 电子邮件对象。
* @return array 修改后的文章数据。
*/
function your_plugin_customize_email_template_post( $post_data, $email_type, $email_data ) {
// 针对特定电子邮件类型修改文章标题。
if ( 'customer_processing_order' === $email_type ) {
$post_data['post_title'] = __( '自定义订单处理电子邮件', 'your-plugin' );
}
// 修改文章内容(块模板 HTML)。
$post_data['post_content'] = str_replace(
'default content',
'custom content',
$post_data['post_content']
);
// 添加自定义元数据。
$post_data['meta_input']['custom_meta_key'] = 'custom_value';
return $post_data;
}
add_filter( 'woocommerce_email_content_post_data', 'your_plugin_customize_email_template_post', 10, 3 );
重要提示:
- 您可以修改任何有效的
wp_insert_post()参数(post_title、post_content、post_excerpt、post_status、post_name、meta_input等)。 - 始终返回修改后的
$post_data数组。 - 在修改
post_content时,请确保保持有效的块标记。 - 该过滤器适用于所有电子邮件类型;使用
$email_type来针对特定电子邮件。
4. 创建初始的阻止模板
创建 templates/emails/block/your-custom-email.php 文件:
模板基础属性: 确保在您的电子邮件类的构造函数中设置 $template_base 属性,使其指向您插件的模板目录。 这允许 WooCommerce 正确地定位和加载您的阻止模板文件。 阻止模板的文件名应与普通模板的文件名相匹配,但使用 block 目录而不是 plain 目录。
<?php
use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
defined( 'ABSPATH' ) || exit;
?>
<!-- wp:heading -->
<h2 class="wp-block-heading"><?php printf( esc_html__( 'Hello %s!', 'your-plugin' ), '<!--[woocommerce/customer-first-name]-->' ); ?></h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php printf( esc_html__( 'Thank you for your order #%s.', 'your-plugin' ), '<!--[woocommerce/order-number]-->' ); ?></p>
<!-- /wp:paragraph -->
<!-- wp:woocommerce/email-content {"lock":{"move":false,"remove":true}} -->
<div class="wp-block-woocommerce-email-content"><?php echo esc_html( BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER ); ?></div>
<!-- /wp:woocommerce/email-content -->
提示: 如果您为电子邮件模板使用自定义路径,请使用电子邮件类的 template_block 属性设置阻止模板路径。
电子邮件内容占位符:
BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER 是一个特殊的占位符,当渲染电子邮件时,它会被替换为主要电子邮件内容。 此占位符对于与 WooCommerce 的电子邮件系统集成至关重要,并允许电子邮件编辑器将核心电子邮件内容(例如订单详情、客户信息等)注入到您的自定义模板中。
默认情况下,WooCommerce 使用 通用阻止电子邮件模板 来生成替换此占位符的内容。 当 WooCommerce 处理您的电子邮件模板时,它会根据电子邮件类型和上下文,用适当的电子邮件内容替换此占位符。
如果您的电子邮件需要使用不同的内容,您有两种选择:
使用自定义阻止内容模板:
-
设置自定义模板: 在您的电子邮件类的构造函数中,将
$template_block_content属性设置为指向自定义阻止内容模板:$this->template_block_content = 'emails/block/custom-content.php'; -
实现自定义逻辑: 在您的电子邮件类中实现
get_block_editor_email_template_content方法,以提供用于生成内容的自定义逻辑:public function get_block_editor_email_template_content() { return '<!-- wp:paragraph --> <p>Your custom block template content here</p> <!-- /wp:paragraph -->'; }
使用动作钩子:
您可以使用动作钩子 woocommerce_email_general_block_email 在内容模板中执行其他操作。
5. 设置触发器
设置邮件发送的时间,可以通过连接到 WordPress 动作来实现。 您可以在 WooCommerce 事件或您自己的自定义动作上触发邮件:
function your_plugin_trigger_custom_email( $order_id ) {
$emails = WC()->mailer()->get_emails();
$email = $emails['YourPlugin_Custom_Email'];
$email->trigger( $order_id );
}
// 在 WooCommerce 订单完成时触发
add_action( 'woocommerce_order_status_completed', 'your_plugin_trigger_custom_email' );
// 在您的自定义插件动作时触发
add_action( 'your_plugin_custom_action', 'your_plugin_trigger_custom_email' );
常用的 WooCommerce 钩子:
woocommerce_order_status_completed- 当订单完成时woocommerce_order_status_processing- 当订单正在处理时woocommerce_new_order- 当创建新订单时woocommerce_customer_created- 当新客户注册时
个性化标签
个性化标签 允许您在邮件中插入动态内容。 它们在您的模板中以 <!--[tag-name]--> 的形式出现,并在发送邮件时被实际值替换。
内置标签
WooCommerce 提供了许多按分类组织的内置个性化标签:
客户标签
<!--[woocommerce/customer-email]-->- 客户的 Email 地址<!--[woocommerce/customer-first-name]-->- 客户的 名<!--[woocommerce/customer-last-name]-->- 客户的 姓氏<!--[woocommerce/customer-full-name]-->- 客户的 全名<!--[woocommerce/customer-username]-->- 客户的 用户名<!--[woocommerce/customer-country]-->- 客户的国家
订单标签
<!--[woocommerce/order-number]-->- 订单号<!--[woocommerce/order-date]-->- 订单日期 (支持格式参数)<!--[woocommerce/order-items]-->- 订单项目 列表<!--[woocommerce/order-subtotal]-->- 订单 小计<!--[woocommerce/order-tax]-->- 订单 税额<!--[woocommerce/order-discount]-->- 订单 折扣 金额<!--[woocommerce/order-shipping]-->- 订单 运费<!--[woocommerce/order-total]-->- 订单 总金额<!--[woocommerce/order-payment-method]-->- 使用的支付方式<!--[woocommerce/order-payment-url]-->- 订单的支付 URL<!--[woocommerce/order-transaction-id]-->- 交易 ID<!--[woocommerce/order-shipping-method]-->- 使用的运输方式<!--[woocommerce/order-shipping-address]-->- 格式化的收货地址<!--[woocommerce/order-billing-address]-->- 格式化的账单地址<!--[woocommerce/order-view-url]-->- 客户订单查看 URL<!--[woocommerce/order-admin-url]-->- 后台订单编辑 URL<!--[woocommerce/order-custom-field]-->- 自定义订单字段 (需要 key 参数)
网站标签
<!--[woocommerce/site-title]-->- 网站标题<!--[woocommerce/site-homepage-url]-->- 主页 URL
商店标签
<!--[woocommerce/store-email]-->- 商店 Email 地址<!--[woocommerce/store-url]-->- 商店 URL<!--[woocommerce/store-name]-->- 商店名称<!--[woocommerce/store-address]-->- 商店地址<!--[woocommerce/my-account-url]-->- "我的账户" 网页 URL<!--[woocommerce/admin-order-note]-->- 管理员订单备注
自定义个性化标签
创建您自己的标签,用于插件特定的数据,使用适当的 WooCommerce 钩子:
/**
* 注册用于邮件编辑器中的自定义个性化标签。
*
* @param \Automattic\WooCommerce\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry $registry 注册表。
* @return \Automattic\WooCommerce\EmailEditor\Engine\PersonalizationTags\Personalization_Tags_Registry
*/
function your_plugin_register_personalization_tags( $registry ) {
// 注册自定义字段标签
$custom_field_tag = new \Automattic\WooCommerce\EmailEditor\Engine\PersonalizationTags\Personalization_Tag(
// 编辑器中的显示名称
__( '自定义字段', 'your-plugin' ),
// Token (唯一标识符)
'your-plugin/custom-field',
// 分类,用于分组
__( '您的插件组', 'your-plugin' ),
// 回调函数
'your_plugin_get_custom_field_value',
// 属性 (可选)
array(),
// 要插入的值 (可选 - 默认为 token)
null,
// 此标签适用的帖子类型
array( 'woo_email' )
);
$registry->register( $custom_field_tag );
return $registry;
}
// 返回自定义字段值的回调函数
function your_plugin_get_custom_field_value( $context, $args = array() ) {
$order_id = $context['order']->get_id() ?? 0;
return get_post_meta( $order_id, '_custom_field', true );
}
// 使用适当的 WooCommerce 钩子进行注册
add_filter( 'woocommerce_email_editor_register_personalization_tags', 'your_plugin_register_personalization_tags' );
在模板中的使用: 在您的块模板中使用 <!--[your-plugin/custom-field]-->,它将被替换为您的回调函数返回的值。
要了解更多关于个性化标签的信息,请参阅 woocommerce/email-editor 软件包中的 个性化标签文档。
提供用于个性化标签的自定义上下文
使用 woocommerce_email_editor_integration_personalizer_context_data 过滤器,向您的个性化标签提供自定义上下文数据。 当您的扩展需要传递额外的 数据(例如,订阅 详情、忠诚度积分或自定义 订单 元 数据),以便您的个性化标签回调函数可以 访问 时,这非常有用。
过滤器 详情:
| 属性 | 价值 |
|---|---|
| 钩子 名称 | woocommerce_email_editor_integration_personalizer_context_data |
| 自版本 | 10.5.0 |
| 参数 | $context (array), $email (\WC_Email) |
| 返回值 | array |
参数:
$context(array) – 现有的上下文 数据 数组。 数组可能已经包含来自 WooCommerce 核心或其它扩展的 数据。$email(\WC_Email) – 正在处理的 WooCommerce 邮件对象。 您可以使用它来 访问 邮件 ID、收件人以及与邮件关联的对象(例如,订单 或客户)。
返回值:
返回一个包含自定义上下文 数据 以及 Woo 核心上下文 数据 的数组。 此数组将通过 $context 参数 提供给所有个性化标签回调函数。
示例:向上下文添加 订阅 数据
/**
* 为个性化标签添加与 *订阅* 相关的上下文 *数据*。
*
* @param array $context 现有的上下文 *数据*。
* @param \WC_Email $email WooCommerce 邮件对象。
* @return array 修改后的上下文 *数据*。
*/
function your_plugin_add_subscription_context( $context, $email ) {
// 仅为与 *订阅* 相关的邮件添加上下文。
if ( strpos( $email->id, 'subscription' ) === false ) {
return $context;
}
// 从邮件对象获取 *订单*。
$order = $email->object instanceof WC_Order ? $email->object : null;
if ( ! $order ) {
return $context;
}
// 将您的自定义 *订阅* *数据* 添加到上下文。
$context['subscription_id'] = $order->get_meta( '_subscription_id' );
$context['subscription_end_date'] = $order->get_meta( '_subscription_end_date' );
$context['renewal_count'] = (int) $order->get_meta( '_renewal_count' );
return $context;
}
add_filter( 'woocommerce_email_editor_integration_personalizer_context_data', 'your_plugin_add_subscription_context', 10, 2 );
示例:在个性化标签的回调函数中使用自定义上下文
一旦您向上下文添加了自定义数据,您的个性化标签回调函数就可以访问它:
/**
* 使用自定义上下文数据的个性化标签回调函数。
*
* @param array $context 上下文数据(包含您的自定义数据)。
* @param array $args 可选的传递给标签的属性。
* @return string 个性化的值。
*/
function your_plugin_get_subscription_end_date( $context, $args = array() ) {
// 访问通过过滤器添加的自定义上下文数据。
$end_date = $context['subscription_end_date'] ?? '';
if ( empty( $end_date ) ) {
return __( 'N/A', 'your-plugin' );
}
// 根据网站设置格式化日期。
return date_i18n( get_option( 'date_format' ), strtotime( $end_date ) );
}
重要提示:
- 该过滤器在电子邮件个性化期间被调用,因此当处理个性化标签时,您的上下文数据是可用的。
- 在向上下文添加数据之前,始终检查电子邮件类型是否相关,以避免不必要的处理。
- 为您的上下文数据使用唯一的键,以防止与 WooCommerce 核心或其他扩展程序发生冲突。
$email->object属性通常包含与电子邮件相关的对象(例如,对于订单电子邮件,是WC_Order;对于与用户相关的电子邮件,是WP_User)。- 在使用个性化标签中的上下文数据时,请确保根据输出上下文进行适当的转义(例如,
esc_html()、esc_attr()、esc_url())。
完整示例
以下是一个忠诚度计划欢迎邮件实现的示例:
邮件类:
class YourPlugin_Loyalty_Welcome_Email extends WC_Email {
public function __construct() {
$this->id = 'loyalty_welcome_email';
$this->title = __( '忠诚度计划欢迎邮件', 'your-plugin' );
$this->customer_email = true;
$this->email_group = 'loyalty';
$this->template_html = 'emails/loyalty-welcome.php';
$this->template_plain = 'emails/plain/loyalty-welcome.php';
$this->template_block = 'emails/block/loyalty-welcome.php';
$this->template_base = plugin_dir_path( __FILE__ ) . 'templates/';
parent::__construct();
}
public function get_default_subject() {
return __( '欢迎加入我们的忠诚度计划!', 'your-plugin' );
}
public function trigger( $customer_id, $points_earned = 0 ) {
$this->setup_locale();
$customer = new WC_Customer( $customer_id );
$this->object = $customer;
$this->recipient = $customer->get_email();
if ( $this->is_enabled() && $this->get_recipient() ) {
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
$this->restore_locale();
}
public function get_content_html() {
return wc_get_template_html( $this->template_html, array(
'customer' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this,
) );
}
public function get_content_plain() {
return wc_get_template_html( $this->template_plain, array(
'customer' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => true,
'email' => $this,
) );
}
}
块邮件:
<!-- wp:heading -->
<h2 class="wp-block-heading"><?php printf( esc_html__( '欢迎 %s!', 'your-plugin' ), '<!--[woocommerce/customer-first-name]-->' ); ?></h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php esc_html_e( '感谢您加入我们的忠诚度计划!', 'your-plugin' ); ?></p>
<!-- /wp:paragraph -->
<!-- wp:woocommerce/email-content {"lock":{"move":false,"remove":true}} -->
<div class="wp-block-woocommerce-email-content"><?php echo esc_html( BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER ); ?></div>
<!-- /wp:woocommerce/email-content -->
注册和设置:
这段代码将所有内容联系起来 - 注册邮件类、模板和触发器:
如何工作:
- 邮件注册 使得您的邮件出现在 WooCommerce > 设置 > 邮件 中。
- 块编辑器注册 允许您的邮件与 WooCommerce 邮件编辑器一起工作。
- 模板注册 允许您注册额外的邮件模板,以便在块编辑器中使用和编辑。
- 触发器设置 自动在客户加入您的忠诚度计划时发送邮件。
详细步骤:
-
注册邮件:
- 通过
woocommerce_email_classes过滤器,将自定义邮件类添加到 WooCommerce 邮件列表中。 - 通过
woocommerce_email_groups过滤器,将自定义邮件分组添加到 WooCommerce 邮件分组中。 - 通过
woocommerce_transactional_emails_for_block_editor过滤器,将自定义邮件注册到块编辑器中。
- 通过
-
设置模板:
- 创建
Email Template,并将其添加到Templates目录中。 - 在
Settings中配置Email Template的Auto发送选项。
- 创建
-
启用和配置:
- 在
Settings中Enable您的邮件功能。 Allow用户Register并Join您的计划。- 配置
Welcome邮件的Setup,包括主题和正文。
- 在
-
发送邮件:
- 使用
Send功能发送Mail。 - 您可以选择
Auto发送,或者手动Edit和发送。
- 使用
示例代码:
// Add the custom email class to the WooCommerce Emails.
add_filter( 'woocommerce_email_classes', function( $classes ) {
$classes['YourPlugin_Loyalty_Welcome_Email'] = new YourPlugin_Loyalty_Welcome_Email();
return $classes;
} );
// Add the custom email group.
add_filter( 'woocommerce_email_groups', function( $email_groups ) {
$email_groups['loyalty'] = __( 'Loyalty Program', 'your-plugin' );
return $email_groups;
} );
// Register the email with the block editor.
add_filter( 'woocommerce_transactional_emails_for_block_editor', function( $emails ) {
$emails[] = 'loyalty_welcome_email';
return $emails;
} );
// Set up trigger - when to send the email
add_action( 'your_plugin_customer_joined_loyalty', function( $customer_id, $points_earned ) {
$emails = WC()->mailer()->get_emails();
$email = $emails['YourPlugin_Loyalty_Welcome_Email'];
$email->trigger( $customer_id, $points_earned );
}, 10, 2 );
常见问题:
- 邮件没有显示在
Settings中: 检查Email registration是否正确配置。 - 邮件无法在块编辑器中使用: 检查
Block editor registration是否正确配置。 - 邮件没有自动发送: 检查
Trigger setup是否正确配置,以及触发条件是否满足。 - 无法
Edit邮件内容: 确保您已注册Email Template,并且可以访问Templates目录。
其他说明:
- 您可以使用
New邮件Class来创建自定义邮件。 - 您可以使用
Edit功能来修改现有的Email Template。 - 您可以使用
Lock功能来防止用户修改某些Settings。 and更多信息,请参考 WooCommerce 的官方文档。
最佳实践
- 清洗输入并转义输出: 始终验证和清洗在邮件逻辑中使用的任何数据,并在模板中转义输出,以防止安全问题和显示问题。
- 在各种邮件客户端进行测试: 邮件布局在不同的客户端可能看起来不同。 使用诸如 Litmus 或 Email on Acid 之类的工具,可以帮助您在流行的客户端(例如 Gmail、Outlook 和 Apple Mail)中测试您的邮件,以确保它们看起来符合预期。
- 使用高效的查询并缓存数据: 在获取用于邮件的数据时,请使用优化的查询,并在可能的情况下缓存结果,以避免降低网站速度。
- 遵循 WordPress 编码规范: 编写符合 WordPress 规范的代码,以提高可读性和兼容性。
- 包含适当的错误处理: 添加检查和错误处理,以便在出现问题(例如缺少数据或发送失败)时能够轻松地检测和调试。
故障排除
- 邮件未显示在管理后台?
仔细检查您的邮件类是否已通过
woocommerce_email_classes过滤器注册,并且类名是否正确。 - 邮件未使用块模板或邮件编辑器?
确保您已通过
woocommerce_transactional_emails_for_block_editor过滤器注册您的邮件 ID。 - 模板未加载? 确保模板文件路径正确,并且您已将其注册到邮件编辑器中。
- 标签无法工作? 确认您的个性化标签回调已注册,并且正在返回预期的值。
- 邮件未发送? 检查邮件是否已在 WooCommerce 设置中启用,并且您的触发操作是否按预期执行。
如何添加商店管理链接
简介
在新的和改进的 WooCommerce 主界面中,有两个扩展点供插件开发者使用,这些扩展点最近受到了广泛关注。第一个是设置任务列表,允许您提醒用户需要完成的任务,并跟踪他们的进度。
第二个是商店管理链接部分。当用户完成设置任务后,此部分将显示给他们。此部分汇总了一系列方便的导航链接,方便商家快速找到 WooCommerce 中的功能。
用户发现功能可能很困难,因此这可以是一个很好的地方,用于突出显示您插件的功能,并允许用户轻松找到您插件提供的关键功能。
添加您自己的商店管理链接是一个简单的过程。
添加您自己的商店管理链接
在开始之前,让我们概述一些关于此功能的限制。
目前,这些链接的设计目的是将用户保留在 WooCommerce 内部,因此不支持外部链接。
您添加的所有链接都将属于列表中的一个特殊分类,称为“扩展”。目前不支持自定义分类。
考虑到这些因素,让我们开始吧。
第一步 - 注册 JavaScript
添加商店管理链接的所有操作都将在 JavaScript 中完成,因此第一步是注册您的脚本,该脚本将添加商店管理链接。最重要的是确保您的脚本在商店管理链接部分渲染之前运行。
为了确保您的脚本在我们脚本之前运行,您需要使用比 15 更高的优先级注册它。您还需要依赖 wp-hooks 以获取 addFilter 的访问权限。
示例:
function enqueue_management_link_script() {
wp_enqueue_script( $script_name, $script_url, array( 'wp-hooks' ), 10 );
}
add_action( 'admin_enqueue_scripts', 'enqueue_management_link_script' );
第二步 - 安装 @wordpress/icons
为了为您的商店管理链接提供您选择的图标,您需要在您的 JavaScript 项目中安装 @wordpress/icons:
npm install @wordpress/icons --save
第三步 - 添加您的过滤器
您的脚本需要使用 addFilter 将您的自定义链接提供给商店管理链接部分。您还需要从 @wordpress/icons 导入您选择的图标。以下是一个示例:
import { megaphone } from "@wordpress/icons";
import { addFilter } from "@wordpress/hooks";
addFilter(
"woocommerce_admin_homescreen_quicklinks",
"my-extension",
(quickLinks) => {
return [
...quickLinks,
{
title: "My link",
href: "link/to/something",
icon: megaphone,
},
];
}
);
以下是使用我们新的自定义商店管理链接的屏幕截图:

为 WooCommerce 扩展创建自定义设置
如果您正在定制 WooCommerce 或为其添加自定义功能,您可能需要一个设置页面。 创建设置页面最简单的方法之一是利用 WC_Integration 类。 使用 Integration 类会自动在 WooCommerce > 设置 > 集成 下创建一个新的设置页面,并且会自动保存和清理您的数据。 我们创建了这个教程,以便您了解如何创建新的集成。
配置集成
创建集成至少需要两个文件,因此您需要创建一个目录。
创建主插件文件
创建您的主插件文件,使用 钩子 挂载到 plugins_loaded 钩子,并检查 WC_Integration 类是否存在。 如果不存在,则用户很可能没有激活 WooCommerce。 完成此操作后,您需要注册该集成。 加载集成文件(稍后会介绍该文件)。 使用 woocommerce_integrations 过滤器,将一个新的集成添加到 数组 中。
创建集成类
现在我们已经完成了框架的搭建,接下来我们来实现这个集成类。 已经存在一个 WC_Integration 类,所以我们想要创建一个 子类。 这样它就能继承所有现有的方法和数据。 你需要为你的集成设置一个 ID、一个描述和一个标题。 这些信息将在集成页面上显示。 你还需要通过调用 $this->init_form_fields(); 和 $this->init_settings(); 来加载设置。 你还需要通过调用 woocommerce_update_options_integration_{你的方法 ID} 钩子来保存你的选项。 最后,你必须输入一些设置来保存! 我们在下面包含了两个虚拟字段,但我们将在下一部分更详细地介绍字段。
添加到名为
class-wc-integration-demo-integration.php的文件中。
<?php
/**
* 集成示例集成。
*
* @package WC_Integration_Demo_Integration
* @category 分类
* @author Patrick Rauland
*/
if ( ! class_exists( 'WC_Integration_Demo_Integration' ) ) :
/**
* 示例集成类。
*/
class WC_Integration_Demo_Integration extends WC_Integration {
/**
* 初始化并注册钩子。
*/
public function __construct() {
global $woocommerce;
$this->id = 'integration-demo';
$this->method_title = __( '集成示例', 'woocommerce-integration-demo' );
$this->method_description = __( '一个集成示例,用于展示如何轻松扩展 WooCommerce。', 'woocommerce-integration-demo' );
// 加载设置。
$this->init_form_fields();
$this->init_settings();
// 定义用户设置的变量。
$this->api_key = $this->get_option( 'api_key' );
$this->debug = $this->get_option( 'debug' );
// 操作。
add_action( 'woocommerce_update_options_integration_' . $this->id, array( $this, 'process_admin_options' ) );
}
WooCommerce 集成示例
简介
本插件演示了如何添加新的 WooCommerce 集成。
术语表
- 已发布: Published
- 设置: Settings
- 安装: Install
- 个人资料: Profile
- 作者: Author
- 调试: Debug
- 错误: Error
- API: API
- 发布者: Published by
- 集成: Integration
- 表单字段: Form fields
- 插件名称: Plugin name
- 调试日志: Debug Log
- 文件名: File name
- 复选框: Checkbox
- 注册: Register
- 版本: Version
- 作者:: Author:
- 版本:: Version:
- 许可证: Licenses
添加到名为
wc-integration-demo.php的文件。
<?php
/**
* 插件名称: WooCommerce 集成示例
* 插件 URI: https://gist.github.com/BFTrick/091d55feaaef0c5341d8
* 描述: 一个插件,演示如何添加新的 WooCommerce 集成。
* 作者: Patrick Rauland
* 作者 URI: http://speakinginbytes.com/
* 版本: 1.0
*
* 本程序是自由软件:您可以根据自由软件基金会发布的 GNU 通用公共许可证(版本 3 或更高版本)的条款重新分发和/或修改它。
*
* 本程序旨在提供帮助,但不对其提供任何保证;不提供任何明示或暗示的保证,包括适销性和特定用途的适用性。有关更多详细信息,请参阅 GNU 通用公共许可证。
*
* 应该随本程序一起提供 GNU 通用公共许可证的副本。如果未提供,请参阅 <http://www.gnu.org/licenses/>。
*
*/
if ( ! class_exists( 'WC_Integration_Demo' ) ) :
/**
* 集成示例类。
*/
class WC_Integration_Demo {
/**
* 构造函数。
*/
public function __construct() {
add_action( 'plugins_loaded', array( $this, 'init' ) );
}
/**
* 初始化插件。
*/
public function init() {
// 检查 WooCommerce 是否已安装。
if ( class_exists( 'WC_Integration' ) ) {
// 包含我们的集成类。
include_once 'class-wc-integration-demo-integration.php';
// 注册集成。
add_filter( 'woocommerce_integrations', array( $this, 'add_integration' ) );
} else {
// 如果需要,可以抛出管理员错误。
}
}
/**
* 初始化集成设置表单字段。
*/
public function init_form_fields() {
$this->form_fields = array(
'api_key' => array(
'title' => __( 'API Key', 'woocommerce-integration-demo' ),
'type' => 'text',
'description' => __( '请输入您的 API Key。您可以在 "个人资料" 下拉菜单(右上角)> API Keys 中找到它。', 'woocommerce-integration-demo' ),
'desc_tip' => true,
'default' => '',
),
'debug' => array(
'title' => __( 'Debug Log', 'woocommerce-integration-demo' ),
'type' => 'checkbox',
'label' => __( '启用日志记录', 'woocommerce-integration-demo' ),
'default' => 'no',
'description' => __( '记录 API 请求等事件。', 'woocommerce-integration-demo' ),
),
);
}
}
endif;
/**
* 向 WooCommerce 添加一个新的集成。
*
* @param array 集成的数组。
*/
public function add_integration( $integrations ) {
$integrations[] = 'WC_Integration_Demo_Integration';
return $integrations;
}
}
endif;
$WC_Integration_Demo = new WC_Integration_Demo( __FILE__ );
创建设置
如果您查看了上一部分,您会看到我们使用 init_form_fields() 方法添加了两个虚拟设置。
设置的类型
WooCommerce 支持 8 种类型的设置。
- text (文本)
- price (价格)
- decimal (小数)
- password (密码)
- textarea (文本域)
- checkbox (复选框)
- select (选择)
- multiselect (多选)
这些设置具有属性,您可以用于自定义它们。 这些属性会影响设置在设置页面上的外观和行为,但不会影响设置本身。 属性的表现方式会根据设置的类型而略有不同。 例如,占位符 (placeholder) 不适用于复选框。 要了解它们的确切工作方式,您应该查看 源代码。 例如:
- title (标题)
- class (类)
- css (CSS)
- placeholder (占位符)
- description (描述)
- default (默认值)
- desc_tip (提示信息)
创建您自己的设置
内置的设置非常棒,但您可能需要额外的控件来创建您的设置页面。这就是为什么我们提供了一些方法来帮助您完成。首先,通过将其添加到 $this->form_fields 数组中来定义一个设置,并在 type 下指定您想要的表单控件类型。您可以通过创建一个以 generate_{ type }_html 命名的函数来覆盖默认的 HTML 标记,该函数将输出 HTML 标记。要指定如何渲染按钮,您需要添加一个名为 generate_button_html 的函数。对于文本区域,您需要添加一个 generate_textarea_html 函数,依此类推。(请查看 WooCommerce 源代码中 WC_Settings_API 类的 generate_settings_html 方法,以了解 WooCommerce 如何使用此方法。)下面的示例创建了一个按钮,该按钮链接到 WooCommerce.com。
/**
* 初始化集成设置表单字段。
*
* @return void
*/
public function init_form_fields() {
$this->form_fields = array(
// 别忘了在这里添加您的其他设置
'customize_button' => array(
'title' => __( '自定义!', 'woocommerce-integration-demo' ),
'type' => 'button',
'custom_attributes' => array(
'onclick' => "location.href='https://woocommerce.com'",
),
'description' => __( '通过直接访问集成站点来自定义您的设置。', 'woocommerce-integration-demo' ),
'desc_tip' => true,
)
);
}
/**
* 生成按钮 HTML。
*
* @access public
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_button_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$defaults = array(
'class' => 'button-secondary',
'css' => '',
'custom_attributes' => array(),
'desc_tip' => false,
'description' => '',
'title' => '',
);
$data = wp_parse_args( $data, $defaults );
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<?php echo $this->get_tooltip_html( $data ); ?>
</th>
<td class="forminp">
<fieldset<
<legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['title'] ); ?></span></legend>
<button class="<?php echo esc_attr( $data['class'] ); ?>" type="button" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php echo $this->get_custom_attribute_html( $data ); ?>><?php echo wp_kses_post( $data['title'] ); ?></button>
<?php echo $this->get_description_html( $data ); ?>
</fieldset>
</td>
</tr>
<?php
return ob_get_clean();
}
数据验证与清洗
为了提供最佳的用户体验,您很可能需要验证和清洗您的数据。 集成类已经执行了基本的清洗操作,以确保没有恶意代码,但您可以通过删除未使用的数据来进一步进行清洗。 清洗数据的示例是与第三方服务集成,其中所有 API 密钥都使用大写字母。 您可以将 API 密钥转换为大写,这对于用户来说会更清晰。
清洗
我们将首先演示如何清洗数据,因为它更容易理解。 但是,您需要记住的一点是,清洗操作发生在 验证 之后。 因此,如果某些数据未通过验证,则不会进入清洗步骤。
/**
* 初始化并注册钩子。
*/
public function __construct() {
// 执行其他构造函数操作
// 过滤器。
add_filter( 'woocommerce_settings_api_sanitized_fields_' . $this->id, array( $this, 'sanitize_settings' ) );
}
/**
* 清洗我们的设置
*/
public function sanitize_settings( $settings ) {
// 我们将 API 密钥转换为大写,因为我们的虚拟 API 这样工作
if ( isset( $settings ) &&
isset( $settings['api_key'] ) ) {
$settings['api_key'] = strtoupper( $settings['api_key'] );
}
return $settings;
}
验证
验证并非总是必要的,但进行验证是很有用的。 如果您的 API 密钥始终是 10 个字符长,并且有人输入了长度不是 10 的密钥,则您可以打印错误信息,并避免用户在他们认为输入正确时遇到的许多问题。 首先,为每个要验证的字段设置一个 validate_{设置键}_field 方法。 例如,对于 api_key 字段,您需要一个 validate_api_key_field() 方法。
public function validate_api_key_field( $key, $value ) {
if ( isset( $value ) && 20 < strlen( $value ) ) {
WC_Admin_Settings::add_error( esc_html__( '看起来您在 API 密钥字段中犯了一个错误。 确保它不超过 20 个字符', 'woocommerce-integration-demo' ) );
}
return $value;
}
一个完整的示例
如果您一直关注,您应该有一个完整的集成示例。 如果您遇到任何问题,请参阅我们的 完整集成演示。
设置 API
WooCommerce 设置 API 用于扩展程序显示、保存和加载设置。 在您的扩展程序中使用 API 的最佳方法是创建一个类,该类继承自 WC_Settings_API 类:
class My_Extension_Settings extends WC_Settings_API {
//
}
定义表单字段
您可以使用类构造函数中的 init_form_fields 方法来定义您的字段:
$this->init_form_fields();
在加载设置之前,您必须定义您的设置。 设置定义应放在 form_fields 数组中:
/**
* 初始化网关设置表单字段。
*/
function init_form_fields() {
$this->form_fields = array(
'title' => array(
'title' => __( 'Title', 'your-text-domain' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'your-text-domain' ),
'default' => __( 'PayPal', 'your-text-domain' )
),
'description' => array(
'title' => __( 'Description', 'your-text-domain' ),
'type' => 'textarea',
'description' => __( 'This controls the description which the user sees during checkout.', 'your-text-domain' ),
'default' => __( "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account", 'your-text-domain' )
)
);
} // End init_form_fields()
(请确保您的类初始化 form_fields 属性,以避免在 PHP 8.2+ 中出现“动态属性创建”错误。)
在上面的示例中,我们定义了两个设置:标题和描述。 标题是一个文本框,而描述是一个文本区域。 请注意,您可以为设置本身定义默认值和描述。
设置定义使用以下格式:
'setting_name' => array(
'title' => '在设置页面上显示的设置标题',
'description' => '在设置页面上显示的设置描述',
'type' => 'text|password|textarea|checkbox|select|multiselect',
'default' => '设置的默认值',
'class' => '输入元素的类',
'css' => '内联添加到输入元素的 CSS 规则',
'label' => '标签', // 仅用于复选框输入。
'options' => array( // 仅用于 select/multiselect 输入的选项数组。
'key' => 'value'
),
)
显示您的设置
创建一个名为 admin_options 的方法,其中包含以下内容:
function admin_options() {
?>
<h2<?php esc_html_e( 'Your plugin name', 'your-text-domain' ); ?></h2>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table>
<?php
}
这将以正确的格式输出您的设置。
保存您的设置
为了使您的设置能够保存,请将您类的 process_admin_options 方法添加到适当的 _update_options_ 钩子中。 例如,支付网关应使用支付网关钩子:
add_action( 'woocommerce_update_options_payment_gateways', array( $this, 'process_admin_options' ) );
其他类型的插件具有类似的钩子:
add_action( 'woocommerce_update_options_shipping_methods', array( $this, 'process_admin_options' ) );
加载您的设置
在构造函数中,您可以加载之前定义的设置:
// 加载设置。
$this->init_settings();
之后,您可以从设置 API 加载您的设置。 上述的 init_settings 方法会为您填充设置变量:
// 定义用户设置的变量
$this->title = $this->settings['title'];
$this->description = $this->settings['description'];
管理 WooCommerce 菜单和分类法归档中的自定义属性
可以用于分层导航的属性是一个自定义分类法,这意味着您可以将其显示在菜单中,或者按属性显示产品。 这需要您进行一些操作,并且必须启用归档功能。
为菜单注册分类法
当注册自定义属性的分类法时,WooCommerce 会调用以下钩子:
$show_in_nav_menus = apply_filters('woocommerce_attribute_show_in_nav_menus', false, $name);
例如,如果您的属性别名为 size,您需要执行以下操作才能将其注册到菜单:
add_filter('woocommerce_attribute_show_in_nav_menus', 'wc_reg_for_menus', 1, 2);
function wc_reg_for_menus( $register, $name = '' ) {
if ( $name == 'pa_size' ) $register = true;
return $register;
}
自定义属性别名以 pa_ 开头,因此名为 size 的属性的别名将是 pa_size。
现在,在 外观 > 菜单 中使用您的属性。 但是,您会注意到,当您单击指向您的分类法项的链接时,它会采用默认的博客样式。
创建一个模板
您需要为您的属性设置主题,以便以您想要的方式显示产品。 要做到这一点:
- 将
woocommerce/templates/taxonomy-product_cat.php复制到您的主题文件夹中。 - 将模板重命名为反映您的属性 - 在我们的示例中,我们将使用
taxonomy-pa_size.php。
现在,当您查看自定义属性的分类法项时,应该会看到此模板。
将管理页面集成到 WooCommerce 扩展中
简介
有多种方法可以管理 WooCommerce 扩展的管理区域页面。 您可以使用现有的 PHP 页面或创建新的基于 React 的页面。 无论您选择哪种方法,您都需要使用 PageController 注册您的页面,以便在您的页面上显示 WooCommerce 管理器标题和活动面板。
将基于 PHP 的页面连接到 WooCommerce 管理器
要将现有的基于 PHP 的管理页面注册到 PageController,请使用 wc_admin_connect_page() 函数。 例如:
wc_admin_connect_page(
array(
'id' => 'woocommerce-settings',
'screen_id' => 'woocommerce_page_wc-settings-general',
'title' => array( 'Settings', 'General' ),
'path' => add_query_arg( 'page', 'wc-settings', 'admin.php' ),
)
);
wc_admin_connect_page() 函数接受一个参数数组,其中两个参数是可选的:
id(必需) - 这用于标识页面和控制器。parent(可选) - 此值将页面标记为父页面的子页面(使用父页面的 ID),并用于生成面包屑。screen_id(必需) - 这对应于PageController::get_current_screen_id()。 它用于确定当前页面。(请参见下面的说明)title(必需) - 这对应于页面的标题,并用于构建面包屑。 您可以在此处提供一个字符串或一个面包屑片段的数组。path(可选) - 这是页面的相对路径。 当此页面是父页面时,用于链接面包屑片段。
在上面的示例中,您可以看到如何使用数组来构建您扩展的面包屑。 WooCommerce 将在标题数组中的第一个片段上附加一个链接,该链接指向 path 值。 所有后续片段都将以文本形式显示,而不会被链接。
关于确定屏幕 ID 的说明
WooCommerce Admin 使用其自己的 get_current_screen() 函数版本,以便更精确地识别管理页面,这些页面可能具有各种标签和子部分。
此 ID 的格式可能因页面上存在的结构元素而异。 该函数将生成以下格式:
{$current_screen->action}-{$current_screen->action}-tab-section{$current_screen->action}-{$current_screen->action}-tab{$current_screen->action}-{$current_screen->action}如果没有标签{$current_screen->action}如果没有操作或标签
如果您的扩展添加了带有标签或子部分的页面,请务必使用 wc_admin_pages_with_tabs 和 wc_admin_page_tab_sections 过滤器,以便 WooCommerce 为它们生成准确的屏幕 ID。
您还可以使用 wc_admin_current_screen_id 过滤器来对屏幕 ID 生成行为进行任何必要的更改。
注册一个基于 React 的页面
要注册一个基于 React 的页面,请使用 wc_admin_register_page() 函数。 它接受一个参数数组:
id(必需) - 这用于标识页面和控制器。parent(可选) - 这将页面标记为parent的子页面(使用父页面的 ID),并用于生成面包屑。title(必需) - 这对应于页面的标题,并用于构建面包屑。 您可以在此处提供一个字符串或面包屑片段的数组。path(必需) - 这是页面的路径(相对于#wc-admin)。 它用于标识此页面,并且当此页面是父页面时,用于链接面包屑片段。capability(可选) - 访问此页面所需的用户权限。 默认值为manage_options。icon(可选) - 使用此选项可以应用 Dashicons 辅助类或 Base64 编码的 SVG。 包含完整的 dashicon 类名,例如dashicons-*。 请注意,这不会包含在 WooCommerce Admin 导航中。position(可选) - 父页面的菜单项位置。 参见:add_menu_page()。
注册一个基于 React 的页面类似于连接一个 PHP 页面,但有一些关键区别。 注册页面将自动为它们创建 WordPress 菜单项,并根据 parent 的值创建适当的层级结构。
示例:添加一个新的 WooCommerce 管理员页面
if ( ! function_exists( 'YOUR_PREFIX_add_extension_register_page' ) ) {
function YOUR_PREFIX_add_extension_register_page() {
if ( ! function_exists( 'wc_admin_register_page' ) ) {
return;
}
wc_admin_register_page( array(
'id' => 'my-example-page',
'title' => __( 'My Example Page', 'YOUR-TEXTDOMAIN' ),
'parent' => 'woocommerce',
'path' => '/example',
) );
}
}
add_action( 'admin_menu', 'YOUR_PREFIX_add_extension_register_page' );
在上面的示例中,我们把对 wc_admin_register_page() 函数的调用封装在一个函数中,并将该函数连接到 admin_menu 动作钩子。 一旦您在控制器中注册了一个页面,您就可以在客户端提供一个 React 组件。
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
const MyExamplePage = () => <h1">My Example Extension</h1>;
addFilter( 'woocommerce_admin_pages_list', 'my-namespace', ( pages ) => {
pages.push( {
container: MyExamplePage,
path: '/example',
breadcrumbs: [ __( 'My Example Page', 'YOUR-TEXTDOMAIN' ) ],
} );
return pages;
} );
在上面的代码中,我们创建了一个简单的 函数式 React 组件 用于演示,但一个真实的扩展程序很可能具有更复杂的组件嵌套结构。
更多阅读
您可以了解更多关于页面注册的工作原理,请查看 WooCommerce 核心代码参考中的 PageController 类。
您可以在 WooCommerce 核心中查看两种页面注册方法的实际示例:
- WooCommerce 如何注册现有的核心页面 - 注册 PHP 驱动的页面
- WooCommerce 如何注册 React 驱动的分析报告页面 - 注册 React 驱动的页面
可访问性
您的扩展程序必须符合 WordPress 可访问性编码规范。
有关可访问性的更多信息,请查看 WordPress 可访问性快速入门指南。
最佳实践
-
插件名称应简洁地描述插件的功能,并且不要在名称中使用现有的核心功能或扩展的名称。 插件名称应始终在用户界面中以一个功能性且独特的名称出现。例如,使用 "Appointments" 而不是 "VendorXYZ Bookings Plugin for WooCommerce"。
-
尽量避免创建新的用户界面。 在考虑创建新的用户界面之前,请先查看 WordPress 界面,看看是否可以将现有组件进行重用。 遵循现有的用户界面导航模式,以便商家在浏览新功能时能够理解其位置。
-
请考虑移动端用户体验(以及面向用户的界面,如果适用)。 商店需要 24/7 全天候运行。 商家不应仅限于在桌面电脑上查看其商店。 扩展程序需要采用响应式设计,以便在所有设备尺寸上都能正常工作。
-
一切围绕商家。 避免使用不相关的内容分散注意力。 始终将产品体验放在首位,以帮助用户完成他们购买您的产品所要执行的任务。
-
在适当的时间呈现评价请求。 向用户呈现评价请求是获取您扩展程序反馈的好方法。 考虑最佳的位置和时机来显示这些提示。
- 避免在首次启动扩展程序时就向用户显示评价请求。 只有当用户有机会设置、连接和使用该插件后,他们才能更好地了解如何对其进行评价。
- 尝试在最不打扰用户的时间点呈现评价请求,例如在成功完成任务或事件后。
-
不要修改核心界面。 不要通过更改 Woo 后台容器的形状来表达您的品牌。
-
专注于用户体验。 在客户安装您的产品后,用户体验应该是首要关注点。 保持简洁,并引导用户完成成功的设置。 不要使体验过于复杂,也不要通过品牌宣传、自我推销、大型横幅或其他任何具有侵入性的内容来分散用户的注意力。
-
保持文本简洁明了。 将界面中的说明限制在 120-140 个字符以内。 任何更长的内容都应放在产品文档中。
-
在与用户沟通时,保持一致的语气。 在扩展程序中,保持相同的沟通风格和术语,避免使用缩写和首字母缩略词。
- 在扩展程序中:
- 使用完整的句子来描述、提供反馈和撰写标题。 避免使用全大写文本。
- 使用标准的标点符号,避免使用过多的感叹号。
- 使用美式英语。
- 更多信息,请阅读我们的 语法、标点符号和大小写指南。
- 在扩展程序中:
颜色
在为 WordPress wp-admin 创建扩展时,请使用核心颜色,尊重用户的 WordPress 管理界面颜色方案选择,并确保您的设计符合 AA 级别指南。
当使用带有文本的组件,例如按钮、卡片或导航时,背景与文本的对比度应至少为 4.5:1,以符合 WCAG AA 标准。请务必 检查您的颜色对比度,以遵守 WCAG 标准。
对于 WooCommerce 相关的颜色使用,请参阅我们的 设计规范。
导航
将您的产品导航元素放置在现有的 WooCommerce 菜单结构中。
带有自身菜单项的扩展
扩展 WooCommerce 菜单结构的两种方式是在分类菜单中或在相关的设置区域中。

分类子导航
如果您的插件扩展了 WooCommerce 的某个区域,它应该直接位于该分类的“部分”中。
例如,TikTok 位于“营销”部分,而“产品附加组件”位于“产品”部分。

设置
如果您的插件添加了一个设置屏幕来配置插件,则设置应该位于 WooCommerce > 设置 屏幕上的适当选项卡下。
例如,配送和支付扩展将出现在其相关的“设置”区域中。 只有在必要时,如果您的扩展具有不适合现有选项卡的设置,并且创建子选项卡不合适,才创建顶级设置选项卡。
不要做:添加顶级导航
如果您的产品扩展了 WooCommerce,那么有 99.9% 的可能性,您的产品导航和设置应该位于 WooCommerce 的导航结构中——请参阅上面的菜单结构示例。
不要做:不要使用 iframe,只使用 API
为了创建一致的体验,应用程序数据应通过 API 加载,而不是通过 iframe。
应该做:保持菜单结构简单
保持菜单结构简单。 尽可能使用现有的 WooCommerce 菜单结构,以减少冗余。
如果您的插件必须引入多个“网页”或区域,请考虑使用现有的“组件”将它们分组在选项卡中,以保持与 WooCommerce 结构的一致性。
没有菜单项的扩展
某些扩展不需要菜单项,因为它们扩展了现有产品区域中的特定功能。
集成的功能包括那些不位于导航中,而是简单地为现有系统添加功能的扩展。 例如,产品捆绑插件仅限于产品表单。
在这种情况下,没有导航项或扩展主屏幕。 “插件”页面可用于与您的用户分享更新。
插件名称
“插件名称”代表了一种让商家在 WooCommerce 后台的多个位置识别您的插件的方式。
不要做:在插件标题中使用现有功能或扩展
“插件名称”应该始终在用户界面中以一个功能性且原创的名称出现。 例如,“预约”,而不是“VendorXYZ WooCommerce 预订插件”。
应该做:单行导航标签
保持扩展名称简短,理想情况下在 20 个“字符”以内,以便商家更容易阅读和理解。
保持所有导航标签在单行显示。 不要使任何菜单项出现第二行。
通知
主要使用通知来响应用户的操作,提供用户反馈。避免使用通知来传达优惠或公告。不要在通知中使用品牌颜色、字体或插图。
如果需要激活后通知,请将其保留在 WordPress 插件区域,不要在仪表盘或其他平台部分显示。
使用标准的 WordPress 通知格式和 WooCommerce 管理通知 API。
语言
提供及时的反馈,例如成功和错误信息,对于确保用户理解是否已进行更改至关重要。
使用简短但有意义的信息,以传达正在发生的情况。确保信息提供用户需要采取的操作以继续。如果信息包含多个句子,请使用正确的标点符号。避免使用缩写。
设计
反馈的位置至关重要,以便用户注意到。例如,当需要验证消息来提示用户输入数据时,通过在需要修改数据的输入框附近显示消息来吸引用户的注意力。

成功 信息:当用户执行的操作成功完成时。
错误信息:当用户执行的操作无法完成时。(这可能包括验证信息。)当需要用户输入数据时,请确保验证每个字段是否符合要求,例如格式、范围以及该字段是否为必填字段。提供与每个字段相邻的验证信息,以便用户可以根据上下文采取行动。避免使用技术术语。
警告信息:当用户执行的操作可能已成功完成,但用户应仔细审查并谨慎操作时。
信息:当需要在用户执行屏幕上的任何操作之前提供信息时。例如,可以在一段时间内的限制或全局设置限制当前屏幕上的操作时提供信息。
示例

入门指南
用户第一次使用您的扩展程序至关重要。当用户首次激活您的扩展程序时,这是一个机会,可以正确引导新用户,并帮助回访用户重新熟悉。用户是否清楚如何开始使用?请记住,如果设置过程过于复杂,用户更有可能完全放弃该产品,因此请保持简单直接。
使用主要按钮作为行动号召,并将次要信息降级,以提高清晰度。 通过清晰的下一步操作和/或带有进度指示器的分步过程,引导商家完成成功的设置,如果扩展程序未配置或设置未完成。
如果需要,请在插件区域提供可关闭的通知。 添加一个通知,以传达下一步操作,如果需要设置或连接才能成功启用插件。
- 使用标准的 WordPress 通知格式和 WooCommerce 管理通知 API。
- 通知应该是可关闭的。用户始终应该有一种明确的方式来关闭通知。
- 将激活后的通知保留在 WordPress 插件区域的插件列表中,不要在仪表盘或其他平台部分显示。
- 不要显示超过一个通知。
- 尽量将通知文本控制在 125 到 200 个字符之间。
如果不需要进行任何设置,最好依赖其他入门辅助功能,例如任务列表(链接到组件)和收件箱(链接到组件),以帮助用户发现功能并使用您的插件。
言简意赅,并提供指导性信息。 这不是宣传您的品牌或推销产品的时机。用户已经购买了您的产品,并准备好使用它。保持信息具有指导性和精确性,避免在空状态和其他入门辅助功能中使用品牌颜色、字体和插图。帮助用户了解下一步的操作。
显示有用的空状态提示。 如果有,请依赖现有的插件 UI,以引导用户成功设置和使用插件。避免使用入门电子邮件、推送通知和欢迎游览。
插件不应在从 WordPress 插件区域激活时进行重定向。 这可能会破坏插件的批量激活。 遵循 dotorg 插件指南 11,该扩展程序不应劫持仪表盘或隐藏核心或其他扩展程序的功能。
避免无效的链接和页面。 始终应该有前进或后退的路径。
错误处理和消息。 如果用户在设置过程中遇到错误,请提供清晰且有用的通知,其中包含关于发生了什么以及如何修复的清晰且易于理解的信息。
设置
使扩展程序的设置易于理解。 仅包含对产品整体功能至关重要的设置选项。
尽可能使用智能默认值, 而不是要求商家进行配置。
直观地分组您的设置。 将常用的设置放在每个部分的顶部,并将具有破坏性或不常用的设置放在底部。
将相关的设置分组在一起, 无论是按使用频率(例如,快速设置)还是按描述(例如,账户设置)。 使用部分标题和子部分标题来创建清晰的层次结构。
避免冗长、乏味的包含许多不同类型设置的列表。 这会让用户感到不知所措,因为他们会觉得产品难以使用。 考虑使用单独的网页或部分来管理不同类型的设置,或者采用逐步显示的方式,优先显示最常用的设置,并隐藏其他所有设置。
使用不带个人色彩的标题和文本, 例如,使用“报告”而不是“我的报告”。 异常:如果为了理解设置而需要提及用户,请使用第二人称(“您”)而不是第一人称(“我”)。
为不易理解的设置或部分提供帮助文本。
使用清晰、一致的语言。 避免使用技术术语。
任务列表和收件箱
插件应根据以下准则,选择实现“任务”笔记或“收件箱”笔记。 避免为同一消息同时实现“任务”和“收件箱”笔记,这会增加混乱并降低消息的影响力。
谨慎使用“任务列表”和“收件箱”。 消息应清晰、简洁,并保持一致的语气。 请遵循 语法、标点符号和大小写指南。
任务列表

需要采取行动的任何事项都应放在任务列表中。
-
以下内容会出现在“待办事项”任务列表中:
- 将启用、连接或配置扩展的任务。
- 对业务至关重要的任务,例如收款或处理争议。
-
以下内容不会出现在“待办事项”任务列表中:
- 任何可能影响或阻止商店正常运行的关键更新,应以标准 WordPress 组件的形式显示为顶级通知。
- 例如,功能公告或插件使用技巧等信息性通知应显示在收件箱中,因为它们不是关键的,也不需要采取行动。
- 来自用户活动的通知应显示为常规反馈通知(成功、信息、错误、警告)。
示例:

收件箱
收件箱为用户提供信息、有用的和补充内容,而重要的通知和设置任务则有其单独的、相关的位置。

-
以下内容会出现在收件箱中:
- 例如,非关键提醒等信息性通知。
- 插件评论和反馈的请求。
- 插件使用技巧和功能介绍。
- 例如,鼓舞人心的消息或里程碑等信息。
-
以下内容不会出现在收件箱中:
- 需要采取行动的通知、扩展设置任务或常规反馈通知。
示例:

测试
用户必须能够执行所有提供的功能的操作。这可以通过运行用户测试来实现。
为了进行有效的用户测试,请列出您的扩展程序支持的尽可能多的场景。例如,一个场景是:“我是一个商店所有者,想要创建一个可定制的产品,该产品允许客户添加自定义文本,并从 5 种不同的颜色选项中选择自定义文本的颜色。” 将此场景提供给测试人员,并观察他们尝试/执行使用您的扩展程序的任务。
以下是一些快速进行用户测试的方法:
- 招募潜在客户来测试您的产品。
- 使用在线服务,这些服务允许您将您的扩展程序暴露给新用户,例如 UserTesting.com。
- 在 WooCommerce 社区 Slack 上向爱好者寻求反馈。
可访问性
您的扩展程序必须符合 WordPress 可访问性编码规范。
有关可访问性的更多信息,请查看 WordPress 可访问性快速入门指南。
颜色
在为 WordPress wp-admin 创建扩展时,请使用核心颜色,尊重用户的 WordPress 管理界面颜色方案选择,并确保您的设计符合 AA 级别指南。
当使用带有文本的组件,例如按钮、卡片或导航时,背景与文本的对比度应至少为 4.5:1,以符合 WCAG AA 标准。请务必 检查您的颜色对比度,以遵守 WCAG 标准。
对于 WooCommerce 相关的颜色使用,请参阅我们的 设计规范。
设置
使扩展程序的设置易于理解。 仅包含对产品整体功能至关重要的设置选项。
尽可能使用智能默认值, 而不是要求商家进行配置。
直观地分组您的设置。 将常用的设置放在每个部分的顶部,并将具有破坏性或不常用的设置放在底部。
将相关的设置分组在一起, 无论是按使用频率(例如,快速设置)还是按描述(例如,账户设置)。 使用部分标题和子部分标题来创建清晰的层次结构。
避免冗长、乏味的包含许多不同类型设置的列表。 这会让用户感到不知所措,因为他们会觉得产品难以使用。 考虑使用单独的网页或部分来管理不同类型的设置,或者采用逐步显示的方式,优先显示最常用的设置,并隐藏其他所有设置。
使用不带个人色彩的标题和文本, 例如,使用“报告”而不是“我的报告”。 异常:如果为了理解设置而需要提及用户,请使用第二人称(“您”)而不是第一人称(“我”)。
为不易理解的设置或部分提供帮助文本。
使用清晰、一致的语言。 避免使用技术术语。
测试
用户必须能够执行所有提供的功能的操作。这可以通过运行用户测试来实现。
为了进行有效的用户测试,请列出您的扩展程序支持的尽可能多的场景。例如,一个场景是:“我是一个商店所有者,想要创建一个可定制的产品,该产品允许客户添加自定义文本,并从 5 种不同的颜色选项中选择自定义文本的颜色。” 将此场景提供给测试人员,并观察他们尝试/执行使用您的扩展程序的任务。
以下是一些快速进行用户测试的方法:
- 招募潜在客户来测试您的产品。
- 使用在线服务,这些服务允许您将您的扩展程序暴露给新用户,例如 UserTesting.com。
- 在 WooCommerce 社区 Slack 上向爱好者寻求反馈。
地址自动补全提供者实现
概述
WooCommerce 地址自动补全系统允许第三方服务在客户在结账过程中输入账单和收货地址时,提供地址建议。本指南解释了如何创建和注册自定义地址提供者,以与任何地址验证服务集成。
请注意,此实现将为短代码和基于块的结账注册提供者。
架构
地址自动补全系统由三个主要组件组成:
- 服务器端提供者 (PHP) - 处理提供者注册和配置
- 客户端提供者 (JavaScript) - 实现搜索和选择逻辑
- UI 组件 - 显示建议并处理用户交互(由 WooCommerce 实现,插件无需提供此功能)
注册服务器端提供者
第一步:创建 WC_Address_Provider 子类
创建一个 PHP 类,该类继承自 WC_Address_Provider:
<?php
/**
* 自定义地址提供者实现
*
* @package YourPlugin
*/
namespace YourPlugin\Providers;
use WC_Address_Provider;
/**
* 自定义地址提供者
*/
class Custom_Address_Provider extends WC_Address_Provider {
/**
* 提供者唯一标识符。
*
* @var string
*/
public $id = 'custom-provider';
/**
* 提供者显示名称。
*
* @var string
*/
public $name = '自定义地址提供者';
/**
* 可选的品牌 HTML,用于在建议中显示。
*
* @var string
*/
public $branding_html = '<div class="custom-branding">提供者:自定义提供者</div>';
/**
* 构造函数
*/
public function __construct() {
// 初始化任何 API 客户端或配置。
}
}
第二步:注册提供者
使用 woocommerce_address_providers 过滤器,将您的提供者注册到 WooCommerce:
/**
* 注册自定义地址提供者
*
* @param array $providers 现有的提供者。
* @return array 修改后的提供者列表。
*/
function register_custom_address_provider( $providers ) {
// 仅在提供者类存在时注册
if ( class_exists( 'YourPlugin\Providers\Custom_Address_Provider' ) ) {
$providers[] = new \YourPlugin\Providers\Custom_Address_Provider();
}
return $providers;
}
add_filter( 'woocommerce_address_providers', 'register_custom_address_provider', 10, 1 );
注册客户端提供者
第三步:实现 JavaScript 函数
创建一个 JavaScript 文件,该文件实现客户端提供者的逻辑。
提供者对象 API
参数
_idstring- 必须与服务器端提供商 ID 匹配的唯一标识符。_canSearchfunction- 用于确定提供商是否支持在给定国家/地区进行搜索的函数。- 参数:
_countrystring- 两位字母的国家/地区代码(例如,'US'、'GB')。
- 返回值:
boolean- 指示提供商是否支持该国家/地区。
- 参数:
_searchfunction- 异步函数,用于搜索地址建议。- 参数:
_querystring- 用户输入的文本(最小 3 个字符)。_countrystring- 所选国家/地区的两位字母国家/地区代码。_typestring- 地址类型,可以是 'billing' 或 'shipping'。
- 返回值:
Promise<Array>- 解决为包含建议对象的数组的 Promise。
- 参数:
_selectfunction- 异步函数,用于检索完整的地址详情。- 参数:
_addressIdstring- 所选建议的 ID。
- 返回值:
Promise<Object|null>- 解决为地址对象或在发生错误时返回 null 的 Promise。
- 参数:
建议对象格式
search 函数必须返回具有以下结构的建议对象:
_idstring- 此建议的唯一标识符。_labelstring- 显示给用户的文本。_matchedSubstringsarray(可选) - 用于突出显示标签中文本范围的文本范围数组。_offsetnumber- 匹配文本的起始位置。_lengthnumber- 匹配文本的长度。
地址对象格式
select 函数必须返回具有以下 WooCommerce 字段名称的地址对象:
_address_1string- 主要地址行。_address_2string- 辅助地址行(可选,可以是空字符串)。_citystring- 城市或城镇名称。_statestring- 州或省份代码。_postcodestring- 邮政编码。_countrystring- 两位字母的国家/地区代码。
示例实现
/**
* 自定义地址提供商客户端实现
*/
// 定义提供商
const customProvider = {
// 必须与 PHP 提供商的 ID 匹配。
id: 'custom-provider',
/**
* 检查提供商是否可以在给定国家/地区进行搜索
*
* @param {string} country - 两位字母的国家/地区代码(例如,'US'、'GB')
* @return {boolean} 提供商是否支持该国家/地区
*/
canSearch: function (country) {
// 定义支持的国家/地区。
const supportedCountries = ['US', 'CA', 'GB', 'AU'];
return supportedCountries.includes(country);
},
/**
* 搜索地址建议
*
* @param {string} query - 用户输入的搜索查询
* @param {string} country - 选择的国家/地区代码
* @param {string} type - 地址类型('billing' 或 'shipping')
* @return {Promise<Array>} 建议对象的数组
*/
search: async function (query, country, type) {
// 返回搜索结果。 您的函数可能调用一个端点来获取这些数据。
const data = [
{
id: '1',
label: '123 Main Street, City, US',
matchedSubstrings: [{ offset: 0, length: 3 }],
},
{
id: '2',
label: '456 Oak Avenue, Town, US',
matchedSubstrings: [{ offset: 0, length: 3 }],
},
{
id: '3',
label: '789 Pine Road, Village, US',
matchedSubstrings: [{ offset: 0, length: 3 }],
},
{
id: '4',
label: '101 Pine Road, Village, US',
matchedSubstrings: [{ offset: 0, length: 3 }],
},
{
id: '5',
label: '101 Pine Road, Village, US',
matchedSubstrings: [{ offset: 0, length: 3 }],
},
];
return data;
},
/**
* 获取所选建议的完整地址详情
*
* @param {string} addressId - 所选建议的 ID
* @return {Promise<Object>} 地址详情对象
*/
select: async function (addressId) {
// 返回地址组件,格式正确。 您的函数可能调用一个端点来获取这些数据。
return {
// 必需的字段
address_1: 'Test address 1',
city: 'Test City',
state: 'CA',
postcode: '92010',
country: 'US',
};
},
};
// 注册提供商。
if (
window.wc &&
window.wc.addressAutocomplete &&
window.wc.addressAutocomplete.registerAddressAutocompleteProvider
) {
window.wc.addressAutocomplete.registerAddressAutocompleteProvider(customProvider);
}
第 4 步:加载 JavaScript
在结账页面加载您的 JavaScript 文件。
即使未将您的服务提供商选择为首选服务提供商,也应加载此 JavaScript 文件。 这是因为,如果首选服务提供商无法搜索结果,您的服务提供商可以作为备用方案。
/**
* 加载自定义服务提供商脚本
*/
function enqueue_custom_provider_scripts() {
// 仅在结账页面加载
if ( is_checkout() ) {
// 检查是否启用了地址自动完成功能
$is_enabled = get_option( 'woocommerce_address_autocomplete_enabled' ) === 'yes';
if ( $is_enabled ) {
wp_enqueue_script(
'custom-address-provider',
plugin_dir_url( __FILE__ ) . 'assets/js/custom-address-provider.js',
array( 'wc-address-autocomplete' ),
'1.0.0',
true
);
// 将数据传递给 JavaScript
wp_localize_script(
'custom-address-provider',
'yourPlugin',
array(
'nonce' => wp_create_nonce( 'wp_rest' ),
'apiUrl' => rest_url( 'your-plugin/v1/' )
)
);
}
}
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_provider_scripts' );
REST API 实现
JavaScript 服务提供商通过 REST API 端点与您的服务器进行通信。 您需要创建两个端点:
-
地址搜索端点 (
/wp-json/your-plugin/v1/address-search)- 接受:查询字符串,国家/地区代码,地址类型
- 返回:包含 ID 和标签的建议数组
-
地址详情端点 (
/wp-json/your-plugin/v1/address-details)- 接受:地址/地点 ID
- 返回:完整的地址组件
有关实现详情,请参阅 WordPress REST API 手册。
故障排除
常见问题
-
服务提供商未在结账页面显示
- 验证服务提供商是否已在服务器上注册
- 检查 JavaScript 文件是否已加载
- 确保 PHP 和 JavaScript 之间的服务提供商 ID 匹配
-
未显示建议
- 检查浏览器控制台中的 JavaScript 错误
- 验证 API 端点是否可访问
- 检查国家/地区是否受服务提供商支持
- 确保搜索查询至少包含 3 个字符
-
选择后字段未填充
- 验证
select方法是否返回正确的字段名称 - 检查地址数据是否与 WooCommerce 字段结构匹配
- 验证
如何向分析报告和 CSV 下载添加列
向分析报告添加列是一种非常有趣的方式,可以为 WooCommerce 添加功能。新的数据可以在用户界面的表格视图中以及用户最喜欢的电子表格或第三方应用程序中使用,通过生成 CSV 文件来实现。
这些说明假设您已安装并激活了一个 WooCommerce 测试插件。您可以按照 "入门" 指令 设置一个测试插件。该帖子还包括进一步修改用于获取数据的查询的说明,以便以更高级的方式进行操作 - 仅添加一个简单的列并非必需。
在 WooCommerce 中,分析 CSV 文件有两种不同的生成方式:一种是在 Web 浏览器中使用已下载的数据,另一种是在服务器上使用新的查询。它使用数据集的大小来确定方法 - 如果结果超过一页,则会在服务器上生成数据,并通过电子邮件向用户发送链接;如果结果适合一页,则会在浏览器中直接生成并下载数据。
我们将首先介绍在服务器上添加列的方法,因为这是生成发送到浏览器的数据的过程。
此示例扩展了“下载”分析报告。为了在您的系统中获取一些用于此报告的数据,请创建一个可下载的产品,并设置下载过期值,然后创建一个购买该产品的订单,并多次下载该产品。在测试中,我创建了 26 次下载,这足以使报告在每页显示 25 个项目时分布在两页,而在每页显示 50 个项目时分布在一页。这使我能够测试在服务器和浏览器中生成的 CSV 文件。
在您的插件的 PHP 代码中,添加三个过滤器处理程序:
// 此代码将 SELECT 片段添加到报告 SQL 中
function add_access_expires_select( $report_columns, $context, $table_name ) {
if ( $context !== 'downloads' ) {
return $report_columns;
}
$report_columns['access_expires'] =
'product_permissions.access_expires AS access_expires';
return $report_columns;
}
add_filter( 'woocommerce_admin_report_columns', 'add_access_expires_select', 10, 3 );
// 此代码将列标题添加到 CSV 文件中
function add_column_header( $export_columns ) {
$export_columns['access_expires'] = 'Access expires';
return $export_columns;
}
add_filter( 'woocommerce_filter_downloads_export_columns', 'add_column_header' );
// 此代码将查询到的项目映射到导出的项目
function map_access_expires( $export_item, $item ) {
$export_item['access_expires'] = $item['access_expires'];
return $export_item;
}
add_filter( 'woocommerce_report_downloads_prepare_export_item', 'map_access_expires', 10, 2 );
这会将访问过期时间戳添加到“下载”表/CSV 文件中(当 CSV 文件在服务器上生成时)。
这些三个过滤器共同作用,将新的列添加到数据库查询中,将新的标题添加到 CSV 文件中,并将从数据库返回的数据映射到 CSV 文件。第一个过滤器 woocommerce_admin_report_columns 向用于数据查询的 SELECT 语句添加一个 SQL 片段。第二个过滤器 woocommerce_filter_downloads_export_columns 向服务器生成的 CSV 文件添加列标题。第三个过滤器 woocommerce_report_downloads_prepare_export_item 将从数据库查询返回的数据 $item 中的值映射到 CSV 文件的导出项。
为了添加对在浏览器中生成的列的支持,还需要将另一个过滤器添加到您的插件的 JavaScript 代码中:
import { addFilter } from "@wordpress/hooks";
function addAccessExpiresToDownloadsReport(reportTableData) {
const { endpoint, items } = reportTableData;
if ("downloads" !== endpoint) {
return reportTableData;
}
reportTableData.headers = [
...reportTableData.headers,
{
label: "访问过期时间",
key: "access_expires",
},
];
reportTableData.rows = reportTableData.rows.map((row, index) => {
const item = items.data[index];
const newRow = [
...row,
{
display: item.access_expires,
value: item.access_expires,
},
];
return newRow;
});
return reportTableData;
}
addFilter(
"woocommerce_admin_report_table",
"dev-blog-example",
addAccessExpiresToDownloadsReport
);
此过滤器首先向 CSV 文件添加标题,然后映射数据。
使用您创建的插件,您现在应该能够将数据添加到分析表、服务器生成的 CSV 文件以及浏览器生成的 CSV 文件中。
如何扩展 WooCommerce 分析报告
简介
本文档旨在指导您如何通过基本的 UI 下拉菜单、添加查询参数以及修改 SQL 查询和最终的报告数据来扩展 WC-Admin 报告。 此示例将创建一个货币选择器,用于根据特定货币查看订单报告。
快速开始
我们将使用 @woocommerce/create-woo-extension 来构建一个现代的 WordPress JavaScript 开发环境,用于插件。 该工具创建了一个完全可用的开发环境,用于与 WooCommerce 集成。
在此示例中,我们将使用 sql-modification 变体来创建一个基本的报告扩展,以便您可以在此基础上进行构建。
在您的 wp-content/plugins 目录中,运行以下命令来创建您的扩展:
npx @wordpress/create-block -t @woocommerce/create-woo-extension --variant=sql-modification my-extension-name
导航到新创建的文件夹并开始开发:
cd my-extension-name
npm run start
可选地,您可以使用 wp-env 来创建一个本地的 WordPress 环境:
npm -g i @wordpress/env
wp-env start
不要忘记前往 /wp-admin/plugins.php 并激活您的插件。
填充测试数据
接下来,设置一些订单以获取示例数据。 在 WooCommerce > 设置 > 货币 中,我添加了三个测试订单,分别使用墨西哥比索、美元和新西兰元。
完成此操作后,请查看 WC-Admin 以确保订单已显示,方法是访问 /wp-admin/admin.php?page=wc-admin&period=today&path=%2Fanalytics%2Forders&compare=previous_year。 请注意,在没有进行任何修改的情况下,货币显示值将根据您在 WooCommerce 设置中当前配置的货币,在本例中为新西兰元。

我们可以通过在 wp_posts 表上运行以下查询并连接 wp_postmeta 来获取元值,来确认每个订单的货币。 结果显示了使用 NZD、USD 和 MXN 的订单。 此查询与我们将在本指南后面实现的查询类似,用于收集和显示货币值。
SELECT
ID,
post_name,
post_type,
currency_postmeta.meta_value AS currency
FROM `wp_posts`
JOIN wp_postmeta currency_postmeta ON wp_posts.ID = currency_postmeta.post_id
WHERE currency_postmeta.meta_key = '_order_currency'
ORDER BY wp_posts.post_date DESC
LIMIT 3

添加一个 UI 下拉菜单
为了以不同的货币查看报告,需要一个过滤器或下拉菜单。 我们可以通过添加一个类似于 订单报告中的这个配置对象 的配置对象,为报告添加一个基本过滤器。
首先,我们需要向客户端提供数据以渲染下拉菜单。 最佳方法是将数据添加到 wcSettings 全局对象中。 此全局对象可用于从 PHP 将静态配置数据传输到客户端。 在主 PHP 文件中,将货币设置添加到数据注册表中,以填充 window.wcSettings.multiCurrency。
function add_currency_settings() {
$currencies = array(
array(
'label' => __( 'United States Dollar', 'dev-blog-example' ),
'value' => 'USD',
),
array(
'label' => __( 'New Zealand Dollar', 'dev-blog-example' ),
'value' => 'NZD',
),
array(
'label' => __( 'Mexican Peso', 'dev-blog-example' ),
'value' => 'MXN',
),
);
$data_registry = Automattic\WooCommerce\Blocks\Package::container()->get(
Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry::class
);
$data_registry->add( 'multiCurrency', $currencies );
}
add_action( 'init', 'add_currency_settings' );
在控制台中,您可以确认数据已安全地传输到客户端。

在 index.js 中,创建自定义货币过滤器,并将其添加到订单报告中。
import { addFilter } from "@wordpress/hooks";
import { __ } from "@wordpress/i18n";
const addCurrencyFilters = (filters) => {
return [
{
label: __("Currency", "dev-blog-example"),
staticParams: [],
param: "currency",
showFilters: () => true,
defaultValue: "USD",
filters: [...(wcSettings.multiCurrency || [])],
},
...filters,
];
};
addFilter(
"woocommerce_admin_orders_report_filters",
"dev-blog-example",
addCurrencyFilters
);
如果查看订单报告,我们可以看到新的下拉菜单。 尝试使用它,您会注意到货币查询参数被添加到 URL 中。 如果查看“网络”选项卡,您还会看到此值包含在用于填充报告的数据请求中。 例如,请查看对订单统计端点的请求,/wp-json/wc-analytics/reports/orders/stats。 接下来,我们将使用该查询参数来调整报告结果。

在服务器端处理货币参数
现在,由于我们的下拉菜单为数据请求添加了一个 currency 查询参数,因此,第一步是将其作为查询参数添加到“订单”数据存储和“订单统计”数据存储中。这些数据存储使用查询参数进行缓存,因此,通过添加我们的参数,我们可以确保在参数更改时执行新的数据库查询。请在您的主 PHP 文件中添加此查询参数。
function apply_currency_arg( $args ) {
$currency = 'USD';
if ( isset( $_GET['currency'] ) ) {
$currency = sanitize_text_field( wp_unslash( $_GET['currency'] ) );
}
$args['currency'] = $currency;
return $args;
}
add_filter( 'woocommerce_analytics_orders_query_args', 'apply_currency_arg' );
add_filter( 'woocommerce_analytics_orders_stats_query_args', 'apply_currency_arg' );
现在,我们已经确保在 currency 查询参数发生变化时执行新的数据库查询,我们可以开始向收集数据的查询中添加 SQL 语句。
首先,为“订单”表、订单统计和订单图表添加一个 JOIN。
function add_join_subquery( $clauses ) {
global $wpdb;
$clauses[] = "JOIN {$wpdb->postmeta} currency_postmeta ON {$wpdb->prefix}wc_order_stats.order_id = currency_postmeta.post_id";
return $clauses;
}
add_filter( 'woocommerce_analytics_clauses_join_orders_subquery', 'add_join_subquery' );
add_filter( 'woocommerce_analytics_clauses_join_orders_stats_total', 'add_join_subquery' );
add_filter( 'woocommerce_analytics_clauses_join_orders_stats_interval', 'add_join_subquery' );
接下来,添加一个 WHERE 子句。
function add_where_subquery( $clauses ) {
global $wpdb;
$currency = 'USD';
if ( isset( $_GET['currency'] ) ) {
$currency = sanitize_text_field( wp_unslash( $_GET['currency'] ) );
}
// Use $wpdb->prepare to safely escape the currency value for SQL.
$prepared_clause = $wpdb->prepare(
'AND currency_postmeta.meta_key = %s AND currency_postmeta.meta_value = %s',
'_order_currency',
$currency
);
$clauses[] = $prepared_clause;
return $clauses;
}
add_filter( 'woocommerce_analytics_clauses_where_orders_subquery', 'add_where_subquery' );
add_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', 'add_where_subquery' );
add_filter( 'woocommerce_analytics_clauses_where_orders_stats_interval', 'add_where_subquery' );
最后,添加一个 SELECT 子句。
function add_select_subquery( $clauses ) {
$clauses[] = ', currency_postmeta.meta_value AS currency';
return $clauses;
}
add_filter( 'woocommerce_analytics_clauses_select_orders_subquery', 'add_select_subquery' );
add_filter( 'woocommerce_analytics_clauses_select_orders_stats_total', 'add_select_subquery' );
add_filter( 'woocommerce_analytics_clauses_select_orders_stats_interval', 'add_select_subquery' );
订单报告
让我们返回到“订单”报告,看看它是否正常工作。您可以操作下拉菜单,并在表格中查看相应的订单信息。

完成最后的调整
Orders 表格可以通过自定义来反映所选的货币。 我们可以通过在 index.js 文件中添加一个列来显示货币。 reportTableData 参数是一个包含表头、行和数据的对象,这些都是数据数组。 我们需要添加一个新的表头,并将货币附加到每一行的 data 数组中。
const addTableColumn = (reportTableData) => {
if ("orders" !== reportTableData.endpoint) {
return reportTableData;
}
const newHeaders = [
{
label: "货币",
key: "currency",
},
...reportTableData.headers,
];
const newRows = reportTableData.rows.map((row, index) => {
const item = reportTableData.items.data[index];
const newRow = [
{
display: item.currency,
value: item.currency,
},
...row,
];
return newRow;
});
reportTableData.headers = newHeaders;
reportTableData.rows = newRows;
return reportTableData;
};
addFilter("woocommerce_admin_report_table", "dev-blog-example", addTableColumn);

虽然添加列很有帮助,但表格和图表中的货币数值仅反映商店的货币。

为了更改报告的货币和数值格式,我们可以使用 woocommerce_admin_report_currency JS 钩子。 您可以在 wcSettings.currency 中看到商店的默认货币,但我们需要根据正在查看的货币以及查询参数 ?currency=NZD 来更改这些设置。

首先,让我们在 index.js 中创建一些配置。
const currencies = {
MXN: {
code: "MXN",
symbol: "$MXN", // 仅为示例。
symbolPosition: "left",
thousandSeparator: ",",
decimalSeparator: ".",
precision: 2,
},
NZD: {
code: "NZD",
symbol: "$NZ",
symbolPosition: "left",
thousandSeparator: ",",
decimalSeparator: ".",
precision: 2,
},
};
最后,将我们的函数添加到钩子中,该钩子会根据货币查询参数应用配置。
const updateReportCurrencies = (config, { currency }) => {
if (currency && currencies[currency]) {
return currencies[currency];
}
return config;
};
addFilter(
"woocommerce_admin_report_currency",
"dev-blog-example",
updateReportCurrencies
);
🎉 现在,我们可以查看我们的 Orders 报告,并在整个报告中看到货币反映在货币数值中。

结论
在本指南中,我们添加了一个用户界面 元素,用于修改发送到 服务器 的 查询参数,并使用这些 参数 的 价值 来 修改 收集报表 数据 的 SQL 语句。 通过这样做,我们建立了一种高度自定义 WC-Admin 报表的方法。 希望这个 例子 能够说明如何通过 扩展 来定制该平台,从而为用户带来强大的体验。
邮件编辑器日志记录
邮件编辑器日志记录使用严重程度阈值,以减少正常运行时的干扰。 默认情况下,只有警告及以上级别的消息会被记录。 要更改日志记录级别,请使用 woocommerce_email_editor_logging_threshold 过滤器:
add_filter( 'woocommerce_email_editor_logging_threshold', function() {
return WC_Log_Levels::DEBUG;
} );
这将启用所有邮件编辑器操作的日志记录,例如邮件编辑器初始化、个性化标签注册等。
有关可用日志级别及其优先级,请参阅 WooCommerce 中的日志记录 文档。
Email HTML - 最佳实践
概述
电子邮件的设计和开发需要一种与传统 Web 开发不同的方法。本指南概述了确保您的 HTML 电子邮件在所有主要电子邮件客户端中正确显示的最佳实践。
关键原则
- 宽度: 保持电子邮件宽度在 600-640px 之间 - 这可确保您的电子邮件在所有设备上正确显示,而不会在较小的屏幕上出现水平滚动条。
- 文件大小: 保持总电子邮件大小低于 100KB - 较大的电子邮件可能会被 Gmail 和其他提供商裁剪,并且在移动设备上加载时间更长。
- 表格: 使用表格进行布局(尽管在 Web 上已被弃用)- 电子邮件客户端对 CSS 的支持不一致,但对表格的渲染非常可靠。
- 测试: 在多个电子邮件客户端和设备上进行测试 - 电子邮件客户端以不同的方式渲染 HTML,测试有助于识别和修复渲染问题。
HTML
使用较旧、更简单的 HTML 标准
- 使用 HTML 4.01 或 XHTML 1.0 - 许多电子邮件客户端使用过时的渲染引擎,不支持现代 HTML5 功能。
- 避免在主要结构中使用 HTML5 元素 - 诸如
<section>、<article>和<aside>之类的元素在所有电子邮件客户端中都未得到支持。 - 始终使用小写字母表示标签和属性 - 这可确保最大的兼容性,并防止在严格的客户端中出现渲染问题。
- 始终为属性值使用引号 - 未加引号的属性可能导致某些电子邮件客户端出现解析错误。
- 关闭所有标签,即使是自闭合标签也应使用尾随斜杠 (
<br />) - 这可防止在期望 XHTML 语法风格的客户端中出现渲染问题。
表格作为基础
- 使用嵌套表格进行布局,而不是基于 div 的布局 - 表格在具有较差 CSS 支持的电子邮件客户端中提供一致的结构。
- 设置明确的单元格内边距、间距和尺寸 - 这可防止在不同的电子邮件客户端中出现不一致的间距和布局。
- 在表格元素和单元格上声明宽度 - 双重声明宽度可以提高渲染的一致性,尤其是在 Outlook 中。
- 使用
align和valign属性,而不是 CSS 等效项 - 这些 HTML 属性在电子邮件客户端中的支持比 CSS 定位更好。
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr">
<td align="center" valign="top">
<!-- 内容在此处 -->
</td>
</tr>
</table>
避免使用有问题的元素
- 不使用 JavaScript - 大多数电子邮件客户端出于安全原因会移除 JavaScript,因此任何依赖于它的功能都将失效。
- 不使用表单(虽然某些客户端支持)- 表单的支持非常不一致;许多客户端会禁用或移除表单元素。
- 不使用 iframe - 这些通常会被大多数电子邮件客户端出于安全原因移除。
- 不使用背景图像(如果必要,可以使用替代方案)- 许多电子邮件客户端默认禁用背景图像。
- 不嵌入音频/视频(而是链接到托管内容)- 直接嵌入的支持较差;链接到外部内容更可靠。
CSS
CSS 支持限制
- 对于所有关键部分,请使用内联 CSS - 许多电子邮件客户端会移除
<style>标签或完全忽略它们。 - 避免使用 CSS 简写属性(使用
margin-top代替margin)- 某些电子邮件客户端只能识别单个属性,而无法识别简写。 - 避免使用 CSS 定位属性 (
position,float,clear) - 这些支持较差,可能会导致布局问题。 - 避免使用高级选择器(坚持使用元素、类和 ID 选择器)- 复杂的选择器通常在具有有限 CSS 支持的电子邮件客户端中无法正常工作。
始终使用内联样式
<p style="font-family: Arial, sans-serif; font-size: 16px; line-height: 24px; color: #333333;">
您的内容在此处
</p>
谨慎使用 style 标签
- 仅用于特定于电子邮件客户端的技巧
- 谨慎使用媒体查询(支持程度各不相同)
- 始终包含
type属性:<style type="text/css">
支持的和不支持的 CSS
支持良好:
font-family,font-size,color- 基本文本样式在电子邮件客户端中的支持较为一致。text-align,line-height- 文本对齐和间距属性在大多数客户端中工作良好。width,height,padding,margin(谨慎使用) - 基本的盒子模型属性在使用时效果良好。 Outlook 中,margin的效果可能不佳。border,background-color- 这些视觉属性在大多数电子邮件客户端中都具有良好的支持。
支持较差或不一致:
- Flexbox, Grid - 现代布局系统在许多电子邮件客户端中不受支持,尤其是 Outlook。
- 定位属性 (
position,display) - 这些可能会导致电子邮件在某些客户端中显示不同或破坏布局。 - CSS 动画 - 这些通常会被大多数电子邮件客户端移除或忽略。
- 许多伪类和伪元素 - 支持不一致;Outlook 和某些 Webmail 客户端会完全忽略它们。
布局技巧
单列设计
- 在所有客户端中都最可靠 - 简单的布局具有较少的故障点。
- 建议宽度:600px - 这可以在大多数预览窗口和移动屏幕中显示。
- 在移动设备上效果良好,无需响应式设计 - 单列布局自然适应窄屏,几乎没有问题。
使用表格的多列布局
<table border="0" cellpadding="0" cellspacing="0" width="600">
<tr>
<td width="300" valign="top">
<!-- Column 1 content -->
</td>
<td width="300" valign="top">
<!-- Column 2 content -->
</td>
</tr>
</table
列堆叠技术
- 在支持的设备上使用媒体查询 - 媒体查询允许在支持它们的客户端上,使列在移动设备上堆叠显示。
- 使用MSO条件评论针对Outlook - 这些专门针对Outlook,Outlook需要特殊的响应式布局处理。
- 考虑对于不支持媒体查询的客户端采用混合/自适应方法 - 这种技术创建的布局即使在没有媒体查询支持的情况下也能合理地适应。
<!--[if mso]>
<table border="0" cellpadding="0" cellspacing="0" width="600">
<tr><td width="300" valign="top"><![endif]-->
<div style="display: inline-block; width: 300px; vertical-align: top;">
<!-- Column 1 content -->
</div>
<!--[if mso]></td><td width="300" valign="top"><![endif]-->
<div style="display: inline-block; width: 300px; vertical-align: top;">
<!-- Column 2 content -->
</div>
<!--[if mso]></td></tr></table><![endif]-->
响应式设计
移动优先策略
- 首先为小屏幕设计 - 移动设备的邮件打开率通常高于桌面设备,因此移动优化至关重要。
- 尽可能使用比例宽度 - 这允许内容根据不同的屏幕尺寸自动适应。
- 使用合适的字体大小(最小14px) - 较小的字体在移动设备上难以阅读,可能需要缩放。
- 确保触摸目标至少为44x44像素 - 这符合可访问性指南,并使触摸屏上的交互更容易。
媒体查询
支持有限但重要:
<style type="text/css">
@media screen and (max-width: 480px) {
.mobile-full-width {
width: 100% !important;
height: auto !important;
}
.mobile-font {
font-size: 16px !important;
}
}
</style>
流式混合方法
使用max-width和MSO条件,可在支持和不支持媒体查询的客户端上工作:
<!--[if mso]>
<table width="600" cellpadding="0" cellspacing="0" border="0"><tr><td>
<![endif]-->
<div style="width:100%; max-width:600px; margin:0 auto;">
<!-- Content -->
</div>
<!--[if mso]>
</td></tr></table>
<![endif]-->
排版
邮件安全字体
始终使用包含广泛支持的字体的字体堆栈:
font-family: Arial, Helvetica, sans-serif;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: 'Times New Roman', Times, serif;
font-family: Verdana, Geneva, sans-serif;
font-family: Georgia, Times, 'Times New Roman', serif;
font-family: 'Courier New', Courier, monospace;
Web 字体
- 支持有限 - 仅在使用适当的备选字体时使用 - 许多电子邮件客户端不支持 Web 字体,因此备选字体至关重要。
- 最可靠的支持:Apple Mail、iOS Mail 和 Android 上的 Google 字体 - 这些客户端能够一致地渲染 Web 字体。
- Outlook、Gmail 和 Yahoo! 通常不支持 Web 字体 - 这些流行的客户端将显示您的备选字体。
<style>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');
</style>
<p style="font-family: 'Open Sans', Arial, sans-serif;">您的文本</p>
文本格式最佳实践
- 将基本字体大小设置为 14-16px - 较小的字体可能难以阅读,尤其是在移动设备上。
- 行高应为字体大小的 1.4-1.6 倍 - 适当的间距可以提高可读性,并防止文本显得拥挤。
- 将大段文本分成小块 - 将内容分解成小块可以提高可读性和用户对电子邮件的参与度。
- 将文本左对齐以获得更好的可读性 - 这可以创建一致的阅读体验,并防止两侧出现不规则的边缘。
- 确保文本和背景之间具有足够的对比度 - 这可以提高所有用户的可读性和可访问性。
图像
图像指南
- 始终包含
alt属性 - 这在图像被阻止时提供文本替代方案,并提高可访问性。 - 为所有图像设置明确的宽度和高度 - 这可以防止图像加载时出现布局偏移,并在图像被阻止时保持结构。
- 保持图像文件大小小 (针对 Web 优化) - 较大的图像会增加加载时间,并可能超出文件大小限制。
- 考虑当图像被阻止时会发生什么 - 许多电子邮件客户端默认会阻止图像,因此您的电子邮件即使在没有图像的情况下也应该仍然易于理解。
<img src="https://example.com/image.jpg" alt="图像描述" width="600" height="400" style="display: block; width: 100%; max-width: 600px; height: auto;" border="0">
背景图像
支持有限;始终提供备用背景颜色:
<table background="https://example.com/bg.jpg" bgcolor="#f7f7f7" width="600" cellpadding="0" cellspacing="0" border="0">
<tr">
<td">
内容
</td>
</tr>
</table>
电子邮件客户端特定设置
Outlook (Windows)
- 使用 Word 渲染引擎 (MSO) - 这解释了 Outlook 的独特渲染特性以及有限的 CSS 支持。
- 需要 VML 来实现背景图像和圆角 - 标准的 CSS 方法对于这些效果在 Outlook 中不起作用。
- 使用 MSO 条件性评论来包含特定于 Outlook 的代码 - 这允许您专门针对 Outlook 版本。
<!--[if mso]>
Outlook 相关的代码
<![endif]-->
Gmail
- 移除样式标签和头部部分 - 所有关键的样式必须使用内联样式。
- 在某些情况下,移除 class 和 ID 属性 - 不要依赖这些属性来实现关键的样式或功能。
- 始终使用内联样式 - 这是在 Gmail 中样式化内容的唯一可靠方法。
- 限制邮件大小(如果太大则会裁剪)- 超过 102KB 的邮件会被裁剪,并显示一个“查看完整消息”的链接。
Apple Mail/iOS
- 最佳的渲染能力 - 这些客户端支持现代 CSS 和 HTML 标准。
- 支持大部分现代 CSS - 如果主要面向 Apple 用户,可以使用 flexbox 和 grid 等特性。
- 良好的媒体查询支持 - 响应式设计在这些平台上可以可靠地工作。
可访问性
语义结构
- 尽可能使用语义化的 HTML (
p,h1,h2等) - 这可以提高屏幕阅读器的解析能力和整体可访问性。 - 为布局表格添加
role="presentation"- 这告诉屏幕阅读器该表格仅用于布局,而不是用于数据展示。 - 包含正确的标题结构 - 这会创建一个逻辑的文档大纲,帮助屏幕阅读器用户浏览。
- 为装饰性元素使用
aria-hidden="true"- 这可以防止屏幕阅读器朗读纯粹的视觉元素。
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
文本替代
- 始终为图像使用描述性的替代文本 - 这可以确保使用屏幕阅读器的用户能够理解图像的内容和目的。
- 为装饰性图像设置空的替代文本 - 这可以防止屏幕阅读器朗读那些不提供信息的图像。
- 考虑在禁用图像时邮件的外观 - 许多用户和邮件客户端会阻止图像,因此内容应该在没有图像的情况下也能正常工作。
颜色和对比度
- 保持正常文本的最小对比度比为 4.5:1 - 这符合 WCAG 可访问性标准,并可以提高所有用户的可读性。
- 使用实际文本,而不是图像中的文本 - 图像中的文本无法被屏幕阅读器访问,并且在不同的设备上缩放效果不佳。
- 不要仅仅依靠颜色来传达信息 - 这可以适应有色觉障碍的用户。
导航和链接
- 使链接易于识别 - 独特的样式可以帮助用户识别可点击的元素。
- 使用描述性的链接文本(避免 "点击这里")- 描述性的链接可以提供上下文,并对使用屏幕阅读器的用户更友好。
- 确保触摸目标之间有足够的间距 - 这可以防止在移动设备上意外点击,并帮助有运动障碍的用户。
测试工具和服务
- 使用专业的邮件测试服务,例如 Litmus 和 Email on Acid。这些平台提供全面的跨多个邮件客户端和设备的测试。
- 尽可能在真实的邮件客户端中进行测试。虽然测试服务很有价值,但实际测试可以发现自动化测试可能无法检测到的问题。
- 检查在桌面和移动客户端中的渲染效果。移动邮件的打开率通常高于桌面,因此移动测试至关重要。
- 在图像被禁用的情况下进行测试。许多邮件客户端默认会阻止图像,因此请确保您的邮件在没有图像的情况下也能被阅读和正常使用。
- 检查垃圾邮件过滤器得分。使用诸如 Mail-Tester 之类的工具来识别邮件内容中潜在的垃圾邮件触发因素。
- 验证 HTML。使用专门用于邮件的验证器,以在发送之前发现潜在的渲染问题。
电子邮件预览集成
概述
WooCommerce 的电子邮件预览功能允许您使用虚拟数据预览电子邮件模板(即,它不使用数据库中的实际数据)。这意味着注册新电子邮件类型的扩展需要与电子邮件预览系统集成,以便正确展示其电子邮件。
集成钩子
以下钩子允许扩展完全控制电子邮件预览:
样式和内容设置
这些钩子允许扩展添加新的样式和内容设置,电子邮件预览会监听这些设置的变化,并在发生变化时更新预览。
woocommerce_email_preview_email_style_setting_ids
添加新的电子邮件样式设置,电子邮件预览会监听这些设置的变化。
add_filter( 'woocommerce_email_preview_email_style_setting_ids', function( $setting_ids ) {
$setting_ids[] = 'my_extension_email_style';
return $setting_ids;
} );
woocommerce_email_preview_email_content_setting_ids
添加新的电子邮件内容设置,电子邮件预览会监听这些设置的变化。
add_filter( 'woocommerce_email_preview_email_content_setting_ids', function( $setting_ids ) {
$setting_ids[] = 'my_extension_email_content';
return $setting_ids;
} );
虚拟数据修改
woocommerce_email_preview_dummy_order
修改在预览中使用的虚拟 WC_Order 对象。
add_filter( 'woocommerce_email_preview_dummy_order', function( $order ) {
// 修改虚拟订单对象
$order->set_currency( 'EUR' );
return $order;
} );
woocommerce_email_preview_dummy_product
修改在预览中使用的虚拟产品。
add_filter( 'woocommerce_email_preview_dummy_product', function( $product ) {
// 修改虚拟产品对象
$product->set_name( 'My Product' );
return $product;
} );
woocommerce_email_preview_dummy_product_variation
修改在预览中使用的虚拟产品变体。
add_filter( 'woocommerce_email_preview_dummy_product_variation', function( $variation ) {
// 修改虚拟变体对象
$variation->set_name( 'My Variation' );
return $variation;
} );
woocommerce_email_preview_dummy_address
修改在预览中使用的虚拟地址。
add_filter( 'woocommerce_email_preview_dummy_address', function( $address ) {
// 修改虚拟地址数组
$address['first_name'] = 'Preview';
$address['last_name'] = 'Customer';
return $address;
} );
占位符和电子邮件对象
woocommerce_email_preview_placeholders
修改要替换到电子邮件中的占位符。
add_filter( 'woocommerce_email_preview_placeholders', function( $placeholders ) {
// 添加自定义占位符
$placeholders['{custom_placeholder}'] = 'Custom Value';
return $placeholders;
} );
woocommerce_prepare_email_for_preview
修改用于预览的 WC_Email 对象。
add_filter( 'woocommerce_prepare_email_for_preview', function( $email ) {
// 修改 email 对象,例如替换 WC_Order
$email->set_object( $custom_object );
return $email;
} );
最佳实践
在与电子邮件预览集成时:
-
使用合适的对象类型
- 为您的扩展使用正确的对象类型(例如,对于 WooCommerce 订阅,使用
WC_Subscription而不是WC_Order)。 - 确保所有必需的属性都已设置在虚拟对象上。
- 为您的扩展使用正确的对象类型(例如,对于 WooCommerce 订阅,使用
-
处理占位符
- 添加您的扩展使用的所有自定义占位符。
- 为占位符提供真实的预览值。
-
样式和内容设置
- 注册所有影响电子邮件外观或内容的所有自定义设置。
-
测试
- 使用不同的电子邮件类型进行预览测试。
- 验证所有自定义内容是否正确显示。
- 检查响应式设计。
故障排除
常见问题和解决方案:
-
我看到 "There was an error rendering an email preview." 错误
- 您的代码中存在 PHP 错误,导致电子邮件预览失败。请检查您的错误日志以获取更多详细信息。
- 或者,您可以修改
class-wc-admin.php并删除try/catchblock 围绕渲染电子邮件预览,以查看错误消息。
-
样式或内容设置的更改未反映
- 确保样式设置已通过
woocommerce_email_preview_email_style_setting_ids过滤器注册。 - 确保内容设置已通过
woocommerce_email_preview_email_content_setting_ids过滤器注册。
- 确保样式设置已通过
-
我没有看到我的扩展的电子邮件
- 确保电子邮件已通过
woocommerce_email_classes过滤器注册。
- 确保电子邮件已通过
邮件编辑器日志记录
邮件编辑器日志记录使用严重程度阈值,以减少正常运行时的干扰。 默认情况下,只有警告及以上级别的消息会被记录。 要更改日志记录级别,请使用 woocommerce_email_editor_logging_threshold 过滤器:
add_filter( 'woocommerce_email_editor_logging_threshold', function() {
return WC_Log_Levels::DEBUG;
} );
这将启用所有邮件编辑器操作的日志记录,例如邮件编辑器初始化、个性化标签注册等。
有关可用日志级别及其优先级,请参阅 WooCommerce 中的日志记录 文档。
HPOS 命令行工具
概述
我们提供了一系列 WP-CLI 命令,用于管理与 HPOS 相关的功能,所有这些命令都位于 wp wc hpos 命名空间下(尽管您可能会在一些博客文章和较旧的文档中看到引用现在已弃用的 wp wc cot 命名空间)。
下表概述了每个命令的功能,更多详细信息和示例请参见下文。
请记住,这些命令本身具有文档和示例,可以通过 WP-CLI 的帮助功能,通过传递 --help 标志来访问。
| 命令 | 使用此命令来... |
|---|---|
wc hpos status |
获取您网站上所有 HPOS 相关的信息。 |
wc hpos enable |
启用 HPOS(以及可能的兼容模式)。 |
wc hpos disable |
禁用 HPOS(以及可能的兼容模式)。 |
wc hpos count_unmigrated |
获取所有待同步订单的数量。 |
wc hpos sync |
高效地将当前活动订单存储中的订单同步到另一个存储。 |
wc hpos verify_data |
验证数据存储之间的信息。 |
wc hpos diff |
获取两个订单存储之间订单差异的易于理解的版本。 |
wc hpos backfill |
将整个订单或特定订单数据从任何订单存储复制到另一个存储。 |
wc hpos cleanup |
从旧表删除订单数据。 |
用法和示例
wc hpos status
使用此命令来获取您网站上 HPOS 的设置和状态。 该命令将输出 HPOS 和兼容模式是否已启用,以及其他有用的信息,例如待同步的订单或需要清理的订单。
注意: 如果需要,可以使用 wc hpos sync 同步待同步的订单,并且,类似地,如果禁用兼容模式,可以运行 wc hpos cleanup all 来清理需要清理的订单。
示例 1 - HPOS 状态输出
$ wp wc hpos status
HPOS 启用?: 是
兼容模式启用?: 否
待同步订单: 651
需要清理的订单: 348
wc hpos enable
使用此命令通过命令行启用 HPOS 和兼容模式(如果需要)。
示例 1 - 通过 CLI 启用 HPOS
启用 HPOS 以及兼容模式(使用 --with-sync 标志)。
$ wp wc hpos enable --with-sync
正在运行预启用检查...
成功: 同步已启用。
成功: HPOS 已启用。
wc hpos disable
类似于前面的命令,此命令可用于禁用 HPOS。
示例 1 - 尝试禁用 HPOS(存在待同步的订单)
如果存在任何待同步的订单,在同步这些订单(通过 wp wc hpos sync)之前,您将无法禁用 HPOS。
$ wp wc hpos disable
正在运行预禁用检查...
错误: [失败] 存在待同步的订单。 请运行 `wp wc hpos sync` 来同步待同步的订单。
示例 2 - 禁用 HPOS
$ wp wc hpos disable
正在执行禁用前的检查...
成功:HPOS 已禁用。
wc hpos count_unmigrated
打印待同步的订单数量。
示例 1 - 获取待同步的订单数量
$ wp wc hpos count_unmigrated
有 651 个订单需要同步。
wc hpos sync
此命令可用于根据 WooCommerce > 设置 > 高级 > 兼容性 中的当前设置,将订单从文章存储迁移到 HPOS(反之亦然)。 也就是说,它会将当前选定的数据存储中的订单同步到另一个数据存储。
请注意,在设置中启用兼容性模式最终将处理所有订单的迁移,但可以使用此命令以更高效的方式执行此操作。
如果您需要更多控制权来选择用作源(或目标)的数据存储,而与设置无关,或者只想迁移几个订单或属性,请使用 wp wc hpos backfill 代替。
示例 1 - 同步所有订单
$ wp wc hpos sync
有 999 个订单需要同步。
订单数据同步 100% [============================================================================================] 0:08 / 0:08
同步完成。
成功:已在 14 **秒**内同步了 999 个订单。
wc hpos verify_data
使用此命令检查传统(文章)数据存储和 HPOS 中的订单数据是否同步。 这仅在启用了“兼容性模式”并且订单可能已在 WooCommerce 的常规流程之外被修改时才相关。
此命令作用于所有订单。 对于更友好的用户替代方案,该方案作用于单个订单,请参阅 wp wc hpos diff。
示例 1 - 验证已迁移站点的属性
所有订单在数据存储之间都相同。
$ wp wc hpos verify_data
订单数据验证 100% [====================================================================================] 0:00 / 0:00
验证完成。
成功:已在 0 **秒**内验证了 999 个订单。
Example 2 - 验证失败
一个订单(ID 为 100126)由于订单总额、税费、修改日期和账单信息存在差异而验证失败。
$ wp wc hpos verify_data
Order Data Verification 100% [====================================================================================] 0:00 / 0:00
Verification completed.
Error: 999 个订单在 0 秒内被验证。发现 1 个错误:{
"100126": [
{
"column": "post_modified_gmt",
"original_value": "2024-04-04 15:32:27",
"new_value": "2024-04-05 15:19:56"
},
{
"column": "_order_tax",
"original_value": "74",
"new_value": "0"
},
{
"column": "_order_total",
"original_value": "567.25",
"new_value": "0"
},
{
"order_id": 100126,
"meta_key": "_billing_address_index",
"orig_meta_values": [
"Hans Howell Moore Ltd 325 Ross Drive Wilfridhaven WA 23322 NF heidi.koch@example.net +17269674166"
],
"new_meta_values": [
"Hans X Howell Moore Ltd 325 Ross Drive Wilfridhaven WA 23322 NF heidi.koch@example.net +17269674166"
]
}
]
}. 请检查上述错误。
Example 3 - 验证期间重新迁移
验证命令还支持 --re-migrate 标志,该标志将尝试同步存在差异的订单。 这可能会有效地覆盖数据库中的一个订单,因此请谨慎使用。
$ wp wc hpos verify_data --re-migrate
Order Data Verification 100% [====================================================================================] 0:00 / 0:00
Verification completed.
Success: 999 个订单在 0 秒内被验证。
wc hpos diff
如果您已启用兼容性模式或使用 wp wc hpos sync 迁移了订单,则所有订单在两个数据存储(旧数据存储和 HPOS)中都应处于相同状态,但可能会发生错误。 此外,手动修改数据库中的订单或使用与 HPOS 不兼容的插件可能会导致订单出现偏差。
wp wc hpos diff 工具可用于检查这些(可能的)差异,这对于确定是否应在任一数据存储之间进行重新迁移,或者是否需要采取更谨慎的方法非常有用。
该工具本身不会解决差异。 要解决这些差异,您应该使用 wp wc hpos backfill。
Example 1 - 订单之间没有差异
订单在两个数据存储(旧数据存储和 HPOS)中相同。
$ wp wc hpos diff 100087
Success: 未发现差异。
示例 2 - 数据存储之间订单属性不一致
这个示例显示,订单 100126 在各个字段上存在差异。 例如,它的 HPOS 版本 状态 为 completed,而该订单仍然处于 pending 状态。 类似地,其他字段也存在差异,并且存在一些元数据 (post_only_meta) 仅存在于旧版本中。
任何未在此处列出的其他订单字段或元数据均被理解为在两个订单版本中相等。
$ wp wc hpos diff 100126
警告:为订单 100126 发现差异:
+--------------------+---------------------------+---------------------------+
| 属性 | hpos | post |
+--------------------+---------------------------+---------------------------+
| 状态 | completed | pending |
| total | 567.25 | 267.25 |
| date_modified | 2024-04-04T15:32:27+00:00 | 2024-04-04T19:00:26+00:00 |
| billing_first_name | Hans | Jans |
| post_only_meta | | why not? |
+--------------------+---------------------------+---------------------------+
示例 3 - JSON 输出
您还可以以各种格式 (json, csv 或 list - 默认格式) 获取输出,这对于将各种订单的差异导出到文件中非常有用。
$ wp wc hpos diff 100126 --format=json
警告:为订单 100126 发现差异:
[{"property":"status","hpos":"completed","post":"pending"},{"property":"total","hpos":"567.25","post":"267.25"},{"property":"date_modified","hpos":"2024-04-04T15:32:27+00:00","post":"2024-04-04T19:00:26+00:00"},{"property":"billing_first_name","hpos":"Hans","post":"Jans"},{"property":"post_only_meta","hpos":"","post":"why not?"}]
wc hpos backfill
backfill 命令可用于选择性地将订单数据(或整个订单)从旧系统或 HPOS 数据存储迁移到另一个数据存储。它对于解决同步或迁移问题非常有用。
此命令的精确语法如下:
wp wc hpos backfill <order_id> --from=<datastore> --to=<datastore> [--meta_keys=<meta_keys>] [--props=<props>]
您必须指定要用作源的数据存储(posts 或 hpos),以及要用作目标的数据存储。--meta_keys 和 --props 参数接收一个逗号分隔的元数据键和订单属性列表,这些键和属性可用于仅移动某些数据,而不是整个订单。
请注意,wp wc hpos backfill 与 wp wc hpos sync 在许多方面有所不同:
- 您可以指定要操作的订单,这使您可以更好地控制一次性操作。
- 它可以让您在 WC 设置中,无论当前订单存储是什么,在数据存储之间移动订单数据。相比之下,
wp wc hpos sync仅将数据从当前数据存储迁移到另一个数据存储。 - 除了允许您迁移完整的订单之外,它还允许您选择要迁移的数据部分(订单字段或元数据)。
示例 1 - 将完整订单从 HPOS 迁移到 posts
$ wp wc hpos backfill 99709
Success: 订单 99709 已从 hpos 迁移到 posts。
示例 2 - 迁移元数据
继续上一部分中的示例 2,我们可以看到如何仅将一个元数据键从 posts 迁移到 HPOS。
$ wp wc hpos backfill 100126 --from=posts --to=hpos --meta_keys=post_only_meta
Success: 订单 100126 已从 posts 迁移到 hpos。
如果您现在运行 wp wc hpos diff 命令,您将看到该元数据不再列为差异。
$ wp wc hpos diff 100126
Warning: 订单 100126 存在差异:
+--------------------+---------------------------+---------------------------+
| 属性 | hpos | post |
+--------------------+---------------------------+---------------------------+
| 状态 | completed | pending |
| 总价 | 567.25 | 267.25 |
| 修改日期 | 2024-04-04T15:32:27+00:00 | 2024-04-04T19:00:26+00:00 |
| 收货人姓氏 | Hans | Jans |
+--------------------+---------------------------+---------------------------+
示例 3
同样,遵循之前的示例,我们现在可以根据需要调整所有数据。 例如,我们可以将订单状态从 posts 迁移到 HPOS,并将其他信息以相反的方向进行迁移。
最终,订单将完全相同,可以通过 wp wc hpos diff 进行确认。
-
同步订单状态从 posts 到 HPOS。 这意味着订单在两个数据存储中都将变为“待审”状态。
$ wp wc hpos backfill 100126 --from=posts --to=hpos --props=status Success: Order 100126 backfilled from posts to hpos. -
同步其他属性从 HPOS 到 posts。
$ wp wc hpos backfill 100126 --from=hpos --to=posts --props=total,date_modified,billing_first_name Success: Order 100126 backfilled from hpos to posts. -
我们是否已经完全同步?
$ wp wc hpos diff 100126 Success: No differences found.
wc hpos cleanup
cleanup 命令可用于在启用 HPOS 且兼容性模式被禁用时,从旧数据表删除订单数据。
由于这是一个破坏性操作,因此该工具默认情况下不会执行任何操作。 您必须指定一个订单 ID、一系列订单 ID 或 all 以对所有订单执行操作。
该工具还会验证订单,并在帖子版本似乎比 HPOS 版本更新时停止,以便更仔细地检查这些差异(例如,使用 wp wc hpos diff),并在执行删除操作之前调整数据(使用 wp wc hpos backfill)。
注意: 此命令不会从 posts 表中删除占位符记录(类型为 shop_order_placehold 的帖子)。 我们正在努力在不久的将来允许这样做,但目前保留占位符,以便在必要时可以切换数据存储。 元数据将被删除,而元数据是旧订单存储中存储大部分数据的区域,因此剩余的占位符帖子非常轻量级。
示例 1 - 清理过程中的错误
默认情况下,清理一个在 posts 数据存储中看起来更新的订单是被禁止的。
$ wp wc hpos cleanup 100126
Starting cleanup for 1 order...
警告:清理订单 100126 时发生错误:posts 表中的数据似乎比 HPOS 表中的数据更新。
您可以使用 wp wc hpos diff 命令来调查差异:
$ wp wc hpos diff 100126
警告:为订单 100126 发现差异:
+---------------+---------------------------+---------------------------+
| 属性 | hpos | post |
+---------------+---------------------------+---------------------------+
| date_modified | 2024-04-05T15:19:56+00:00 | 2024-04-05T16:39:26+00:00 |
+---------------+---------------------------+---------------------------+
如果不需要进行同步,可以使用 --force 标志来跳过验证检查:
$ wp wc hpos cleanup 100126 --force
Starting cleanup for 1 order...
HPOS cleanup 100% [=====================================================================================================================] 0:00 / 0:00
成功:已完成 1 个订单的清理。
示例 2 - 清理一系列订单 ID
$ wp wc hpos cleanup 90000-100000
Starting cleanup for 865 orders...
HPOS cleanup 100% [=====================================================================================================================] 0:01 / 0:12
成功:已完成 865 个订单的清理。
示例 3 - 清理所有订单
$ wp wc hpos cleanup all
Starting cleanup for 999 orders...
HPOS cleanup 100% [=====================================================================================================================] 0:01 / 0:05
成功:已完成 999 个订单的清理。
如何启用高性能订单存储
自 WooCommerce 8.2 起,于 2023 年 10 月发布,对于新安装的项目,高性能订单存储默认已启用。 现有商店可以通过以下步骤,从“WordPress 帖子存储”切换到“高性能订单存储”。
要激活高性能订单存储,现有商店首先需要将帖子表和订单表同步,可以通过启用以下设置来实现: "启用兼容模式(将订单同步到帖子表)"。
-
导航至 WooCommerce > 设置 > 高级 > 功能
-
启用 "启用兼容模式(将订单同步到帖子表)" 设置。

-
启用此设置后,将安排后台操作。
wc_schedule_pending_batch_process操作检查是否有需要回填的订单。- 如果有,它会安排另一个操作
wc_run_batch_process,该操作实际上将订单回填到帖子存储中。 - 您可以等待这些操作自行运行,这应该很快完成,或者您可以转到 WooCommerce > 状态 > 计划任务,找到这些操作并点击“运行”按钮。
- 该操作每次回填 25 个订单,如果还有更多订单需要同步,则在完成前一个操作后,将安排更多操作。

-
在两个表成功同步后,您将能够选择切换到高性能订单存储 (HPOS) 的选项。
- 建议在一段时间内保持兼容模式,以确保平稳过渡。 如果出现任何问题,可以立即恢复到帖子表。
大型商店启用 WooCommerce HPOS 的指南
您是否运行一个高流量的 WooCommerce 商店?您是否即将开始在您的商店上启用高性能订单存储 (HPOS)? 随着越来越多的高流量商店迁移到 HPOS,我们决定记录一些指南,以帮助那些可能面临这项任务的用户。
开始之前
第一阶段:在本地开发系统中测试 HPOS
如果您为您的网站设置了本地开发环境,您可以在您的开发环境中尝试 HPOS。 确保您已在测试站点上启用所有插件以及任何自定义代码,并且正在运行其最新版本。 测试环境应尽可能地模拟您的生产环境。
至少,我们建议您关注以下测试:
- 测试每种支付方式的结账功能。
- 测试这些结账的退款流程。
- 如果您正在使用 WooCommerce 订阅,请检查订阅是否可以购买以及续订是否可以正常进行。
- 您为您的网站定义的任何关键流程。
您可以重复这些测试,分别在启用和禁用同步的情况下进行。
请记住,您可以 切换同步,方法是转到 WooCommerce > 设置 > 高级 > 功能,并切换 "启用兼容性模式" 复选框。

审查:第一阶段检查清单
- 确保您的测试站点的代码是最新的,通过安装所有 WooCommerce 相关插件的最新版本。
- 测试每种支付方式的结账功能。
- 验证测试结账的退款流程。
- 如果安装了 WooCommerce 订阅,请测试订阅的购买和续订。
- 在启用和禁用同步的情况下,测试关键的网站流程。
第二阶段:在测试环境中进行迁移和测试
当您对本地环境中的运行情况感到满意时,是时候将生产数据库复制到测试环境,并测试 HPOS 迁移。对于大型网站,我们建议启用同步,但不要依赖计划任务来执行迁移,您可以使用命令行界面 (CLI) 来加快速度:具体来说,是 wp wc hpos sync 命令。
为了了解最终迁移(在生产环境)所需的时间,请务必记录此命令的运行时间。例如,对于我们的测试商店,该商店有 900 万个订单,完成迁移大约需要一周的时间。
为了获得额外的安心,您可以运行 wp wc hpos verify_cot_data --verbose 命令来检查数据是否已成功迁移。
在测试环境中完成迁移后,并且仍然启用同步,请重新运行第一阶段中定义的测试。禁用同步,并再次进行所有测试。
测试第三方和外部系统
您可能有一些非 PHP 系统直接连接到数据库,这些系统可能不会被常规代码审计所发现。请验证您是否有诸如数据仓库、配送跟踪系统、会计系统等系统,确保它们没有直接读取文章表。如果它们正在读取,则需要在继续执行下一步之前对其进行更新。
审查:第二阶段检查清单
- 确保您的测试环境中的代码是最新的,通过安装所有正在使用的 WooCommerce 相关插件的最新版本。
- 使用 CLI 将生产数据库迁移到测试环境。
- 监控迁移时间,以了解生产环境迁移的持续时间。
- 在启用同步的情况下,在测试环境中测试第一阶段的流程。
- 可选:使用
wp wc hpos verify_cot_data --verbose命令验证数据迁移的完整性。 - 在禁用同步的情况下,在测试环境中测试第一阶段的流程。
- 审计第三方系统,以确保它们没有直接访问文章表。
第三阶段:在生产环境中启用 HPOS
如果您对在本地环境和测试环境中的测试结果感到满意,现在是时候开始在生产环境中启用 HPOS 了。
启用同步,保持 WordPress 文章作为订单存储
就像在之前的阶段一样,您应该在启用同步的同时,继续使用 WordPress 文章作为订单存储。通常,您可以通过转到 WooCommerce > 设置 > 高级 > 功能,并确保选择 使用 WordPress 文章表作为订单数据存储 来执行此操作。
这将确保订单开始出现在 HPOS 表格中,并且现有的订单将保持最新状态。
迁移和验证数据
现在,开始迁移过程,通过启用“启用兼容模式”复选框来启动同步。
在启用同步后,您可以使用 wp wc hpos sync 命令,通过命令行界面 (CLI) 将过去的订单从文章表迁移到新的 HPOS 表。
如果出现任何错误,停止同步或中断 CLI 任务是安全的。 您可以在解决错误后(或如果错误与同步过程无关时)重新开始。
可选地,您还可以运行验证命令 (wp wc hpos verify_cot_data --verbose) 以检查迁移的数据是否符合预期。
重要:即使 CLI 任务已完成,也不要立即关闭同步。 对于生产环境,我们建议逐步禁用同步:首先禁用读取时的同步,然后完全禁用同步。
此外,在我们最近的大批量商店迁移过程中,即使保持同步启用状态(并且文章具有权威性),我们也未观察到明显的负面性能影响。
切换到 HPOS 作为权威数据源
现在是切换到 HPOS 的时候了。 转到 WooCommerce > 设置 > 高级 > 功能,并将 HPOS 设置为权威数据源(选择“使用 WooCommerce 订单表”)。
如上所述,请勿立即关闭同步。 如果出现任何问题,系统可以立即恢复到文章表,从而不会造成停机。
重新检查您在先前阶段中的所有关键流程,并进行一些测试。 确保测试使用各种付款方式的结账流程以及您的关键流程。 在高流量的商店,您应该会自然地收到一些订单,请打开其中的一些订单并验证所有订单数据是否已按预期填充。 此外,请关注您的支持或联系渠道。
提示: 如果您的商店有自然低流量时期,我们建议您在此期间进行切换,但您应该计划在切换后保持在线一段时间。 切换到 HPOS 或在需要时恢复到文章表都是热迁移,不需要任何计划的停机时间。
禁用读取时的同步
在前面的步骤中,您已启用具有同步功能的 HPOS,现在是时候逐步禁用同步,以便开始享受 HPOS 的大部分优势。 此过程的第一步是禁用读取时的同步,您可以通过以下代码片段来完成:
add_filter( 'woocommerce_hpos_enable_sync_on_read', '__return_false' );
我们首先禁用读取时的同步,因为它需要更多的资源。 如果您的网站运行状况良好,并且您看到一些订单正在进来,您可以禁用读取时的同步。 在我们的大批量商店迁移中,我们仅在设置 HPOS 为权威数据源后 6 小时就禁用了读取时的同步。
关闭写入时的同步
如果一切运行如预期,您可以禁用写入时的同步。 既然读取时的同步已经禁用,您可以从 设置 中完全禁用同步。 像往常一样,转到 WooCommerce > 设置 > 高级 > 功能,取消选中 "启用兼容模式"。
在我们的高流量网站上,我们在一周后完全禁用了同步。 我们仍然定期手动同步(通过 wp wc hpos sync 命令),以便在出现任何问题时,我们可以立即回退到文章数据存储。
请记住,禁用同步不会移除回退到文章数据存储的能力,但您需要等待迁移作业将文章表中的任何缺失数据填充到 HPOS 表中。 始终可以使用 wp wc hpos sync 命令来实现此目的。
现在,在完全禁用同步后,请测试各种关键流程,检查订单是否以预期的自然方式流入,并密切关注您的支持和联系渠道。
审查:第三阶段检查清单
- 计划在线并监控您的实时网站一段时间。
- 启用与文章设置为权威的数据同步:在 WooCommerce > 设置 > 高级 > 功能 中,选择 "使用 WordPress 文章表"。
- 使用
wp wc hpos sync命令启动迁移。 - 监控迁移过程中的错误;根据需要停止或恢复。
- 使用验证命令
wp wc hpos verify_cot_data验证迁移数据的完整性。 - 启用与 HPOS 设置为权威的数据同步:在 WooCommerce > 设置 > 高级 > 功能 中,选择 "使用 WooCommerce 订单表"。
- 测试所有关键流程,使用多种 付款方式 进行 结账,并验证订单数据的准确性。
- 监控 支持 渠道,查看是否有任何问题。
- 使用提供的代码片段禁用读取时的同步:
add_filter( 'woocommerce_hpos_enable_sync_on_read', '__return_false' ); - 监控网站性能。
- 在稳定运行一周后,完全禁用同步。
- 持续监控网站性能、订单处理和 支持 渠道。
一般指南
- 尽可能使测试环境与生产环境相似。
- 记录在测试和迁移过程中遇到的任何问题。
- 定期与利益相关者沟通测试进度和结果。
- 计划潜在的回退场景,确保在出现问题时能够回退到文章。
HPOS 扩展使用指南
什么是高性能订单存储 (HPOS)?
直到最近,WooCommerce 将与订单相关的数据存储在数据库中的 post 和 postmeta 表中,作为一种自定义 WordPress 帖子类型。这使得生态系统中的每个人都可以利用 WordPress 核心提供的广泛 API 来管理订单,并将订单视为自定义文章类型。
然而,在 2022 年初,我们 宣布了迁移到专用于订单的表的计划。将订单存储在自己的表中,可以使商店更容易扩展、简化数据存储并提高可靠性。有关更多详细信息,请查看我们 关于数据库结构的深入分析。
通常,WooCommerce 努力与旧版本完全兼容,但是,由于这个项目,扩展开发者需要对他们的插件进行一些更改,以利用 HPOS。这是因为底层的数据结构发生了根本性的变化。
更具体地说,开发者不再需要使用 WordPress 提供的 API 来访问订单数据,而是需要使用 WooCommerce 专用的 API。我们 在 WooCommerce 版本 3.0 中引入了这些 API,以简化向 HPOS 的过渡。
在本指南中,我们将重点介绍使扩展程序或任何自定义代码片段与 HPOS 兼容所需的更改。
有关如何启用或禁用 HPOS 的详细信息,以及有关订单如何在不同数据存储之间同步的详细信息,请参阅 HPOS 文档。
向后兼容性
为了使商店和开发者都能更轻松地过渡,我们尽可能地保持向后兼容。这个项目的主要兼容性问题之一是,由于底层的数据结构是 wp_posts 和 wp_postmeta 表,因此绕过 WooCommerce 专用的 CRUD 类,直接使用 WordPress API 访问数据是可行的。
现在情况已经改变,直接从这些 WordPress 表中读取数据可能会读取到过时的订单,而直接写入这些表可能会更新一个无法读取的订单。由于这是一个非常严重的问题,我们为过渡期添加了一些缓解措施。
切换数据源
此外,如果您在使用新表时遇到问题,您可以手动从 HPOS 切换回 post 表。要切换回旧模式,请在 WC > 设置 > 高级 > 功能中更改“订单数据存储”设置。
支持扩展中的高性能订单存储
虽然向后兼容性政策使商家更容易使用该项目,但对于扩展开发者来说,这意味着您需要同时支持 Posts 和 HPOS 运行一段时间。
为了帮助开发者,我们提供了一些指南供您参考。
注意: 我们建议您在开发扩展时使用 WooCommerce 的开发版本,以便获得最新的 HPOS 修复和 API。请参考我们的 开发指南,了解 WooCommerce 仓库的结构以及如何从源代码构建插件。
检测商店是否正在使用 HPOS 表格
虽然 WooCommerce CRUD API 通常可以使您在大多数情况下同时支持 Posts 和自定义表格,但在某些情况下(例如,当您编写 SQL 查询以提高性能时),您可能需要知道商店是否正在使用 HPOS 表格。在这种情况下,您可以使用以下模式:
use Automattic\WooCommerce\Utilities\OrderUtil;
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
// HPOS 已启用。
} else {
// 正在使用传统的基于 CPT 的订单。
}
检查代码库中是否存在直接数据库访问
为了支持 HPOS 表格,一个好的起点是检查您的代码库中是否存在直接数据库访问以及使用不再应用于处理订单的 WordPress API。您可以使用以下正则表达式进行此检查:
wpdb|get_post|get_post_field|get_post_status|get_post_type|get_post_type_object|get_posts|metadata_exists|get_post_meta|get_metadata|get_metadata_raw|get_metadata_default|get_metadata_by_mid|wp_insert_post|add_metadata|add_post_meta|wp_update_post|update_post_meta|update_metadata|update_metadata_by_mid|delete_metadata|delete_post_meta|delete_metadata_by_mid|delete_post_meta_by_key|wp_delete_post|wp_trash_post|wp_untrash_post|wp_transition_post_status|clean_post_cache|update_post_caches|update_postmeta_cache|post_exists|wp_count_post|shop_order
请注意,您会发现很多误报,但此正则表达式相当全面,应该可以捕获大多数真正的匹配项。
在您的源代码中搜索上述正则表达式,并:
- 逐个检查匹配项,并检查该匹配项是否与订单相关。 大多数匹配项很可能都是误报,即它们与订单无关。
- 如果您看到某个匹配项直接访问或修改订单数据,则需要将其更改为使用 WooCommerce 的 CRUD API。
获取/设置文章和文章元数据的 API
任何直接获取文章的代码都可以转换为 wc_get_order 调用:
// 替代方案
$post = get_post( $post_id ); // 返回 WP_Post 对象。
// 使用
$order = wc_get_order( $post_id ); // 返回 WC_Order 对象。
要与元数据进行交互,请使用订单对象的 update_/add_/delete_metadata 方法,然后调用 save。 WooCommerce 会自动处理确定哪些表处于活动状态,并将数据保存在适当的位置。
// 替代以下更新/添加/删除方法,使用:
update_post_meta( $post_id, $meta_key_1, $meta_value_1 );
add_post_meta( $post_id, $meta_key_2, $meta_value_2 );
delete_post_meta( $post_id, $meta_key_3, $meta_value_3 );
// 使用
$order = wc_get_order( $post_id );
$order->update_meta_data( $meta_key_1, $meta_value_1 );
$order->add_meta_data( $meta_key_2, $meta_value_2 );
$order->delete_meta_data( $meta_key_3, $meta_value_3 );
$order->save();
注意: 调用 save() 方法是一个相对耗时的操作,因此您可能希望避免不必要地多次调用它(例如,如果您知道稍后将在同一流程中调用它,则在对同一对象进行操作时,您可能希望避免额外的早期调用)。
要获取订单的确切类型,或者检查给定的 ID 是否为订单,可以使用 OrderUtil 类的 方法。
// 检查 ID 是否为订单的模式
'shop_order' === get_post_type( $post_id ); // 或者
in_array( get_post_type( $post_type ), wc_get_order_types() );
// 替换为:
use Automattic\WooCommerce\Utilities\OrderUtil;
'shop_order' === OrderUtil::get_order_type( $post_id ); // 或者
OrderUtil::is_order( $post_id, wc_get_order_types() );
订单管理界面函数审计
由于 WC 无法使用 WordPress 提供的帖子列表和帖子编辑界面,我们还添加了新的订单管理界面。这些界面与您在 WooCommerce 管理后台中看到的界面非常相似(除了它们使用 HPOS 表)。您可以使用以下正则表达式来执行此审计:
post_updated_messages|do_meta_boxes|enter_title_here|edit_form_before_permalink|edit_form_after_title|edit_form_after_editor|submitpage_box|submitpost_box|edit_form_advanced|dbx_post_sidebar|manage_shop_order_posts_columns|manage_shop_order_posts_custom_column
您可能会在这里看到很多误报。但是,如果您发现这些方法被用于订单界面,则需要进行以下更改才能将其升级到 HPOS:
您需要使用 WC_Order 类的 $order 对象,而不是 WP_Post 类的 $post 对象。如果它是一个过滤器或操作,我们将在新的 WooCommerce 界面中实现类似的过滤器,并且它将接受一个 WC_Order 对象,而不是传递帖子对象。
以下代码片段展示了一种在旧的订单编辑器界面(当使用旧订单时)和新的 HPOS 驱动的编辑器界面中添加元数据框的方法:
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
add_action( 'add_meta_boxes', 'add_xyz_metabox' );
function add_xyz_metabox() {
$screen = class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' ) && wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled()
? wc_get_page_screen_id( 'shop-order' )
: 'shop_order';
add_meta_box(
'xyz',
'自定义元数据框',
'render_xyz_metabox',
$screen,
'side',
'high'
);
}
上述代码还会更改传递给元数据框的参数,因此在您的元数据框中,您需要考虑到可能传递的帖子对象或订单对象。我们建议获取订单对象并完全使用它,而不是使用传递的参数。
function render_xyz_metabox( $post_or_order_object ) {
$order = ( $post_or_order_object instanceof WP_Post ) ? wc_get_order( $post_or_order_object->ID ) : $post_or_order_object;
// ... 代码的其余部分。在此点之后,不应直接使用 $post_or_order_object。
}
声明扩展的兼容性 (或不兼容性)
在您检查了扩展的代码后,您可以声明该扩展是否与 HPOS 兼容。 我们提供了一个 API 来简化此过程。 要声明您的扩展兼容,请将以下代码放置在您的主插件文件中:
add_action( 'before_woocommerce_init', function() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
} );
如果您知道您的代码不支持 HPOS,您应该以以下方式声明不兼容性。 将以下代码放置在您的主插件文件中:
add_action( 'before_woocommerce_init', function() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, false );
}
} );
如果您希望在主插件文件之外包含兼容性声明,请将 'my-plugin-slug/my-plugin.php' 传递给上面的代码片段中的 __FILE__ 参数,而不是直接使用 __FILE__。
为了防止出现问题,如果任何不兼容的插件处于激活状态,WooCommerce 会向用户发出警告,提示他们不要启用 HPOS。 它还会在插件屏幕上显示一个警告,以确保用户了解该扩展是否不兼容。
由于许多 WordPress 扩展与 WooCommerce 无关,因此 WC 只会为在主插件文件的标题中声明了 WC tested up to 的扩展显示此信息。
新的订单查询 API
HPOS 通过 WC_Order_Query 引入了新的查询类型,这些类型允许进行更复杂的订单查询,涉及日期、元数据和订单字段。 请访问 HPOS: 新的订单查询 API 以获取详情和示例。
HPOS 订单查询 API
随着 HPOS 的引入,我们增强了 WC 中的查询功能。现在,除了众所周知的 现有 API,我们添加了一些功能,可以更轻松地创建复杂的订单或其属性的查询,包括查询自定义订单元数据的能力。
所有新的查询类型都实现为额外的查询参数,这些参数可以传递给 wc_get_orders() 函数,并且深受 WordPress 自己的 WP_Query 中类似功能的启发。 像常规的查询参数一样,它们可以与其他参数组合,以生成复杂的查询,而这些查询在过去需要编写自定义代码和 SQL。
新的查询类型
元数据查询 (meta_query)
随着 HPOS 的引入,以前存储为帖子元数据的订单字段已移动到其自己的表中,但剩余的元数据(自定义或来自其他扩展)现在可以通过 meta_query 参数进行查询。
从根本上说,meta_query 是一个数组,它可以包含一个或多个具有以下键的数组:
key (元数据键名),
value (元数据值)
compare (可选) 用于比较的运算符,例如 LIKE、RLIKE、NOT BETWEEN、BETWEEN 等。
type 用于在查询中将元数据值转换为特定的 SQL 类型。
不同的数组还可以使用 relation(允许 'AND' 或 'OR' 值)组合起来,以生成更复杂的查询。 此新参数的语法与 WP_Query 的 meta_query 完全相同。 因此,您可以参考 meta_query 文档,以获取更多详细信息。
// 示例:获取所有具有 "color" 键的元数据的订单(任何值),以及具有 "size" 键且包含 "small" 的元数据的订单(例如,也会匹配 "extra-small")。
$orders = wc_get_orders(
array(
'meta_query' => array(
array(
'key' => 'color',
),
array(
'key' => 'size',
'value' => 'small',
'compare' => 'LIKE'
),
),
)
);
订单字段查询 (field_query)
这种查询类型具有与元查询 (meta_query) 相似的语法,但它使用 field 替代 key,在不同的子句中使用 field。 在这里,field 指的是任何订单属性(例如 billing_first_name、total 或 order_key 等),这些属性也可以像往常一样作为顶级键在查询参数中访问。 直接查询这些属性与使用 field_query 之间的区别在于,您可以通过实现比较运算符以及组合或嵌套来创建更复杂的查询。
// 示例。 对于简单的查询,最好直接使用订单属性,即使存在 `field_query` 的等效方法。
$orders = wc_get_orders(
array(
'billing_first_name' => 'Lauren',
'order_key' => 'my_order_key',
)
);
$orders = wc_get_orders(
array(
'field_query' => array(
array(
'field' => 'billing_first_name',
'value' => 'Lauren'
),
array(
'field' => 'order_key',
'value' => 'my_order_key',
)
)
)
);
field_query 的真正强大之处在于,当您想要执行更复杂的查询时,这些查询以前是无法实现的。
// 示例。 获取所有总价或配送总价小于 5.0 的订单。
$orders = wc_get_orders(
array(
'field_query' => array(
'relation' => 'OR',
array(
'field' => 'total',
'value' => '5.0',
'compare' => '<',
),
array(
'field' => 'shipping_total',
'value' => '5.0',
'compare' => '<',
),
)
)
);
日期查询 (date_query)
日期查询允许您通过查询与其关联的日期(date_completed、date_created、date_updated、date_paid)以各种方式来获取订单。
date_query 的语法与 WP_Query 中的 date_query 完全兼容。 因此,一个很好的示例和详细信息的来源是 WP 代码库中的 meta_query 文档。
// 示例。 获取所有在过去一个月内支付的,并且在任何日期之前创建的订单。
$orders = wc_get_orders(
array(
'date_query' => array(
'relation' => 'AND',
array(
'column' => 'date_created_gmt',
'hour' => 12,
'compare' => '<'
),
array(
'column' => 'date_paid_gmt',
'after' => '1 month ago',
),
),
)
);
高级示例
// 获取状态为 "on-hold" 或 "pending",且元数据 `weight` >= 50,并且元数据 `color` 或 `size` 存在的订单。
$query_args = array(
'status' => array( 'pending', 'on-hold' ),
'meta_query' => array(
array(
'key' => 'weight',
'value' => '50',
'compare' => '>=',
),
array(
'relation' => 'OR',
array(
'key' => 'color',
'compare' => 'EXISTS',
),
array(
'key' => 'size',
'compare' => 'EXISTS',
)
),
)
);
$orders = wc_get_orders( $query_args );
// 获取在账单详情中,名包含 "laur" 的订单(例如,匹配 "lauren" 和 "laura"),并且订单总额小于 10.0,且总折扣 >= 5.0。
$orders = wc_get_orders(
array(
'field_query' => array(
array(
'field' => 'billing_first_name',
'value' => 'laur',
'compare' => 'LIKE',
),
array(
'relation' => 'AND',
array(
'field' => 'total',
'value' => '10.0',
'compare' => '<',
'type' => 'NUMERIC',
),
array(
'field' => 'discount_total',
'value' => '5.0',
'compare' => '>=',
'type' => 'NUMERIC',
)
)
),
)
);
WooCommerce 支付网关 API
WooCommerce 中的支付网关基于类,可以通过传统的插件进行添加。本指南提供支付网关开发的入门介绍。
支付网关的类型
支付网关有多种类型:
- 基于表单 - 用户必须点击表单上的一个按钮,然后被重定向到支付处理商的网站。示例: PayPal 标准版,Authorize.net DPM
- 基于 iFrame - 支付网关的支付系统加载在您的商店的 iFrame 中。示例: SagePay Form,PayPal 高级版
- 直接 - 支付字段直接显示在结账页面上,用户在点击“提交订单”按钮时完成支付。示例: PayPal Pro,Authorize.net AIM
- 离线 - 不进行在线支付。示例: 支票,银行转账
基于表单和 iFrame 的网关会将数据发送到外部服务器,这意味着您需要考虑的安全问题较少。但是,直接网关需要实施服务器安全措施(例如,SSL 证书),并且可能需要满足一定的 PCI 合规性 标准。
创建基本的支付网关
注意: 以下说明适用于默认的结账页面。如果您想为新的结账块添加自定义支付方式,请查看 支付方式集成文档。
支付网关应该作为附加插件创建,并与 WooCommerce 集成。在插件内部,您需要在插件加载后创建一个类。例如:
add_action( 'plugins_loaded', 'init_your_gateway_class' );
重要的是,您的网关类应该继承 WooCommerce 的基本网关类,以便您可以使用重要的方法和 设置 API。
function init_your_gateway_class() {
class WC_Gateway_Your_Gateway extends WC_Payment_Gateway {}
}
您可以在 API 文档中查看 WC_Payment_Gateway 类。
除了定义您的类之外,您还需要告诉 WooCommerce (WC) 它的存在。通过过滤 woocommerce_payment_gateways 来实现:
function add_your_gateway_class( $methods ) {
$methods[] = 'WC_Gateway_Your_Gateway';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_your_gateway_class' );
必需的方法
大多数方法是从 WC_Payment_Gateway 类继承的,但某些方法需要在您的自定义网关中实现。
__construct()
在您的构造函数中,您应该定义以下变量:
$this->id- 您的网关的唯一 ID,例如 'your_gateway'$this->icon- 如果您想在前端显示网关名称旁边的图像,请输入指向图像的 URL。$this->has_fields- 布尔值。 如果您希望在结账页面显示支付字段(如果进行直接集成),则可以将其设置为 true。$this->method_title- 在管理页面上显示的支付方法标题。$this->method_description- 在管理页面上显示的支付方法描述。
您的构造函数还应该定义和加载设置字段:
$this->init_form_fields();
$this->init_settings();
稍后我们将介绍 init_form_fields(),但它基本上定义了您的设置,然后使用 init_settings() 加载。
在调用 init_settings() 之后,您可以获取设置并将它们加载到变量中,例如:
$this->title = $this->get_option( 'title' );
最后,您需要添加一个保存钩子,用于您的设置:
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
init_form_fields()
使用此方法来设置 $this->form_fields - 这些是在您的网关设置页面上的管理界面中显示的选项,并使用 WC 设置 API。
您的网关的基本设置应包括 启用/禁用、标题 和 描述:
$this->form_fields = array(
'enabled' => array(
'title' => __( '启用 / 禁用', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( '启用支票支付', 'woocommerce' ),
'default' => 'yes'
),
'title' => array(
'title' => __( '标题', 'woocommerce' ),
'type' => 'text',
'description' => __( '这控制用户在结账过程中看到的标题。', 'woocommerce' ),
'default' => __( '支票支付', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( '客户消息', 'woocommerce' ),
'type' => 'textarea',
'default' => ''
)
);
process_payment( $order_id )
现在,我们来看网关最重要的部分:处理支付和处理订单。 process_payment 函数还会告诉 WooCommerce 将用户重定向到哪里,这通过返回的数组来实现。
以下是 Cheque 网关中 process_payment 函数的一个示例:
function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
// 标记为待处理 (我们正在等待支票)
$order->update_status('on-hold', __( 'Awaiting cheque payment', 'woocommerce' ));
// 清空购物车
$woocommerce->cart->empty_cart();
// 返回感谢页面重定向
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
如您所见,它的作用是:
- 获取并更新正在处理的订单
- 返回成功状态和重定向 URL (在本例中是感谢页面)
Cheque 网关将订单状态设置为“待处理”,因为无法自动验证支付。 但是,如果您正在构建一个直接网关,则可以在此处完成订单。 不要使用 update_status 来更新已支付的订单,而应该使用 payment_complete:
$order->payment_complete();
这可以确保库存减少,并将状态更改为正确的值。
如果支付失败,您应该抛出错误并返回一个包含失败状态的数组:
wc_add_notice( __('Payment error:', 'woothemes') . $error_message, 'error' );
return array(
'result' => 'failure'
);
WooCommerce 会捕获此错误并在结账页面上显示它。
库存级别是通过操作 (woocommerce_payment_complete 以及订单状态之间的转换) 进行更新的,因此在处理支付时,不再需要手动调用减少库存级别的函数。
更新订单状态和添加备注
可以使用订单类中的函数来更新订单状态。 只有当订单状态不是“处理中”时,才应这样做(在这种情况下,您应该使用 payment_complete())。 更新为自定义状态的示例:
$order = new WC_Order( $order_id );
$order->update_status('on-hold', __('Awaiting cheque payment', 'woothemes'));
上面的示例将状态更新为“待处理”,并添加一条备注,告知所有者正在等待支票。 可以在不更新订单状态的情况下添加备注;这用于添加调试消息:
$order->add_order_note( __('IPN payment completed', 'woothemes') );
订单状态的最佳实践
- 如果订单已完成,但管理员需要手动验证支付,请使用 On-Hold 状态。
- 如果订单失败并且已创建,请将其设置为 Failed 状态。
- 如果支付已完成,请让 WooCommerce 处理状态,并使用
$order->payment_complete()。 WooCommerce 将使用 Completed 或 Processing 状态,并处理库存。
关于直接支付网关的说明
如果您正在创建一个高级、直接支付网关(即,一个在实际的结账页面上进行支付的网关),则涉及的步骤会更多。首先,您需要在网关构造函数中设置 has_fields 为 true:
$this->has_fields = true;
这会告诉结账系统输出一个名为 'payment_box' 的区域,其中包含您定义的直接支付表单。
创建一个名为 payment_fields() 的方法,该方法包含您的表单,通常会包含信用卡详细信息。
下一个可选的方法是 validate_fields()。如果表单通过验证,则返回 true;如果验证失败,则返回 false。您可以使用 wc_add_notice() 函数来添加错误信息并在用户界面上显示。
最后,您需要在 process_payment( $order_id ) 方法中添加支付代码。此代码接收已提交的表单数据,并尝试直接通过支付提供商进行支付。
如果支付失败,您应该输出一个错误信息并返回失败数组:
wc_add_notice( __('Payment error:', 'woothemes') . $error_message, 'error' );
return array(
'result' => 'failure',
);
如果支付成功,您应该将订单状态设置为已支付,并返回成功数组:
// 支付完成
$order->payment_complete();
// 返回感谢页面重定向
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
使用支付网关回调(例如 PayPal IPN)
如果您正在构建一个网关,该网关会向您的商店发送回调,以告知您订单的状态,则需要在您的网关中添加代码来处理此操作。
添加回调和回调处理程序最好的方法是使用 WC-API 钩子。一个例子是 PayPal Standard 的做法。它将回调/IPN URL 设置为:
str_replace( 'https:', 'http:', add_query_arg( 'wc-api', 'WC_Gateway_Paypal', home_url( '/' ) ) );
然后,它将处理程序挂载到该钩子上:
add_action( 'woocommerce_api_wc_gateway_paypal', array( $this, 'check_ipn_response' ) );
当访问该 URL 时,WooCommerce 会调用您的网关并运行该操作。
有关更多信息,请参阅 WC_API - WooCommerce API 回调。
网关中的钩子
重要的是要注意,在网关类中添加钩子可能不会触发。网关仅在需要时才会被加载,例如在结账过程中和在管理后台的设置页面。
如果您需要从您的类中挂载到 WordPress 事件,请将钩子放在类外部,或者使用 WC-API。
WooCommerce 支付网关插件基础
这段代码可以作为基础,用于创建您自己的简单的自定义支付网关,适用于 WooCommerce。 如果您没有将其用于自定义插件,则需要将此代码添加到子主题的 functions.php 文件中,或者通过允许添加自定义函数的插件,例如 Code snippets 插件。 请不要直接将自定义代码添加到父主题的 functions.php 文件中,因为在更新主题时,这些代码将被完全清除。
<?php
/*
Plugin Name: WooCommerce <enter name> 网关
Plugin URI: https://woothemes.com/woocommerce
Description: 为 WooCommerce 扩展一个 <enter name> 网关。
Version: 1.0
Author: WooThemes
Author URI: https://woothemes.com/
Copyright: © 2009-2011 WooThemes.
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
add_action('plugins_loaded', 'woocommerce_gateway_name_init', 0);
function woocommerce_gateway_name_init() {
if ( !class_exists( 'WC_Payment_Gateway' ) ) return;
/**
* 本地化
*/
load_plugin_textdomain('wc-gateway-name', false, dirname( plugin_basename( __FILE__ ) ) . '/languages');
/**
* 网关类
*/
class WC_Gateway_Name extends WC_Payment_Gateway {
// 您可以在这里自由发挥
}
/**
* 将网关添加到 WooCommerce
**/
function woocommerce_add_gateway_name_gateway($methods) {
$methods[] = 'WC_Gateway_Name';
return $methods;
}
add_filter('woocommerce_payment_gateways', 'woocommerce_add_gateway_name_gateway' );
}
WooCommerce 支付令牌 API
WooCommerce 2.6 引入了一个 API,用于存储和管理网关的支付令牌。用户还可以从他们的账户设置中管理这些令牌,并在结账时从已保存的支付令牌中进行选择。
本指南提供了一些有用的教程,用于使用新的 API,以及您可用的各种方法。
教程
为您的网关添加支付令牌 API 支持
在以下示例中,我们将使用 Simplify Commerce 网关。
步骤 0:扩展正确的网关基础类
WooCommerce 提供了两个用于网关的基础类。这些类与令牌 API 一起在 2.6 中引入。它们是 WC_Payment_Gateway_CC(用于基于信用卡的令牌)和 WC_Payment_Gateway_eCheck(用于基于电子支票的令牌)。它们包含一些用于在结账时生成支付表单的有用代码,并且应该能够覆盖大多数情况。
如果您需要,您还可以通过扩展抽象类 WC_Payment_Gateway 来实现您自己的网关基础类。
由于 Simplify 处理信用卡,因此我们扩展了信用卡网关。
class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway_CC
步骤 1:'Supports' 数组
我们需要告诉 WooCommerce 我们的网关支持令牌化。与其他网关功能一样,这在网关的 __construct 方法中,在一个名为 supports 的数组中定义。
这是 Simplify 的数组:
$this->supports = array(
'subscriptions',
'products',
...
'refunds',
'pre-orders',
);
将 tokenization 添加到此数组中。
第二步:定义一种方法,用于从“我的账户”中添加/保存新的付款方式
当从“我的账户”部分添加新的付款方式时,将调用表单处理程序,该处理程序会调用网关的 add_payment_method 方法。
您的 add_payment_method 应该返回一个包含两个键的数组,一个 result 字符串和一个 redirect URL:
array(
'result' => 'success', // 或者 'failure'
'redirect' => wc_get_endpoint_url( 'payment-methods' ),
);
在进行任何验证(即,确保从支付提供商处获取了所需的令牌和数据)后,您可以开始构建一个新的令牌,方法是创建以下类之一的实例:WC_Payment_Token_CC 或 WC_Payment_Token_eCheck。 类似于网关,您也可以扩展抽象类 WC_Payment_Token 并定义您自己的令牌类型,如果需要的话。有关这三个类及其方法的更多信息,请参阅本文档的后续部分。
由于 Simplify 使用信用卡,因此我们将使用信用卡类。
$token = new WC_Payment_Token_CC();
我们将使用各种 set_ 方法来传递有关我们令牌的信息。 首先,我们将传递令牌字符串和网关 ID,以便将令牌与 Simplify 相关联。
$token->set_token( $token_string );
$token->set_gateway_id( $this->id ); // `$this->id` 引用在 `__construct` 中设置的网关 ID
此时,我们可以设置任何其他我们想要存储在令牌中的必要信息。 信用卡需要卡类型(Visa、MasterCard 等)、卡号的后四位、到期月份和到期年份。
$token->set_card_type( 'visa' );
$token->set_last4( '1234' );
$token->set_expiry_month( '12' );
$token->set_expiry_year( '2018' );
在大多数情况下,您还希望将令牌与特定用户关联:
$token->set_user_id( get_current_user_id() );
最后,在构建了令牌对象后,我们可以将令牌保存到数据库中。
$token->save();
如果令牌已成功保存,save 将返回 true;如果发生错误(例如缺少字段),则返回 false。
第三步:在结账时保存付款方式
WooCommerce 还允许客户在“我的账户”之外,在结账过程中保存新的付款令牌。您需要添加一些代码到您的网关的 process_payment 函数中,以使其正常工作。
要确定是否需要保存新的付款方式,您可以检查以下 POST 字段,如果选择了“保存到账户”复选框,则该字段应返回 true。
wc-{$gateway_id}-new-payment-method
如果您之前为用户提供了已保存的令牌,您还可以查看 wc-{$gateway_id}-payment-token 字段,如果该字段的值为 new,则表示选择了“使用新卡”/“使用新的付款方式”单选按钮。
一旦确定需要保存令牌,您就可以像在第二步中那样,使用 set_ 和 save 方法来保存令牌。
第 4 步:处理支付时获取令牌
如果用户选择了某个令牌,您需要在网关中处理支付时检索该已保存的令牌。这应该也在您的 process_payment 方法中完成。
您可以使用类似于以下的代码片段来检查是否应使用现有令牌:
if ( isset( $_POST['wc-simplify_commerce-payment-token'] ) && 'new' !== $_POST['wc-simplify_commerce-payment-token'] ) {
wc-{$gateway_id}}-payment-token 将返回所选令牌的 ID。
然后,您可以从 ID 加载令牌(稍后在本文档中将详细介绍 WC_Payment_Tokens 类):
$token_id = wc_clean( $_POST['wc-simplify_commerce-payment-token'] );
$token = WC_Payment_Tokens::get( $token_id );
这不会检查加载的令牌是否属于当前用户。您可以使用简单的检查来完成此操作:
// 令牌用户 ID 与当前用户 ID 不匹配... 停止支付处理。
if ( $token->get_user_id() !== get_current_user_id() ) {
// 可选地使用 `wc_add_notice` 显示通知
return;
}
在加载了令牌并执行了任何必要的检查后,您可以使用 $token->get_token() 来获取实际的令牌字符串(以便将其传递给您的支付提供商)。
创建新的令牌类型
如果您提供的电子支票 (eCheck) 和信用卡 (CC) 令牌类型不能满足您的需求,您可以扩展抽象类 WC_Payment_Token 并创建新的令牌类型。 如果您这样做,则需要包含一些内容。
第 0 步:扩展 WC_Payment_Token 并命名您的类型
首先,扩展 WC_Payment_Token 并为新的类型提供一个名称。 让我们看看 eCheck 令牌类的构建方式,因为它是在 WooCommerce 核心中提供的最基本的令牌类型。
一个最基本的令牌文件的外观如下:
class WC_Payment_Token_eCheck extends WC_Payment_Token {
/** @protected string 令牌类型字符串 */
protected $type = 'eCheck';
}
此令牌类型的名称为 'eCheck'。 $type 中提供的值需要与类名匹配(即:WC_Payment_Token_$type)。
第一步:提供一个验证方法
在将令牌保存到数据库之前,会执行一些基本的验证。WC_Payment_Token 检查实际令牌值是否已设置,以及上面定义的 $type。 如果您想验证其他数据的存在(例如,eCheck 需要最后 4 位数字)或长度(到期月份应为 2 个字符),您可以提供自己的 validate() 方法。
validate() 方法应返回 true,如果一切正常;如果出现问题,则返回 false。
始终确保在添加自己的逻辑之前,调用 WC_Payment_Token 的 validate() 方法。
public function validate() {
if ( false === parent::validate() ) {
return false;
}
现在,我们可以添加一些逻辑来处理“最后 4 位”数字。
if ( ! $this->get_last4() ) {
return false;
}
最后,如果顺利执行到 validate() 方法的末尾,则返回 true。
return true;
}
第二步:为额外数据提供 get_ 和 set_ 方法
现在,您可以为每个您想要公开的数据添加自己的方法。 提供了方便的函数,可以轻松地存储和检索数据。 所有数据都存储在元数据表中,因此您无需创建自己的表或向现有表添加新字段。
为每个您想要捕获的数据提供一个 get_ 和 set_ 方法。 对于 eCheck,这是“last4”,表示支票的最后 4 位数字。
public function get_last4() {
return $this->get_meta( 'last4' );
}
public function set_last4( $last4 ) {
$this->add_meta_data( 'last4', $last4, true );
}
就此为止! 这些元数据函数由 WC_Data 提供。
第三步:使用您的新令牌类型
现在,您可以直接在创建新令牌时使用您的新令牌类型:
`$token = new WC_Payment_Token_eCheck();`
// 设置令牌属性
$token->save()
或者,当使用 WC_Payment_Tokens::get( $token_id ) 时,它将返回您的新令牌类型。
类
WC_Payment_Tokens
此类提供了一组有用的方法,用于与支付令牌进行交互。 所有方法都是静态的,可以在不创建类的实例的情况下调用。
get_customer_tokens( $customer_id, $gateway_id = '' )
返回一个包含 $customer_id 中指定客户的令牌对象的数组。 您可以通过提供网关 ID 来按网关进行过滤。
// 获取当前用户的全部令牌
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() );
// 获取用户 42 的全部令牌
$tokens = WC_Payment_Tokens::get_customer_tokens( 42 );
// 获取当前用户的所有 Simplify 令牌
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id(), 'simplify_commerce' );
get_customer_default_token( $customer_id )
返回标记为“默认”的支付令牌对象(即在结账时自动选择的令牌)。 如果用户没有默认支付令牌/没有支付令牌,此函数将返回 null。
// 获取当前用户的默认支付令牌
$token = WC_Payment_Tokens::get_customer_default_token( get_current_user_id() );
// 获取用户 520 的默认支付令牌
$token = WC_Payment_Tokens::get_customer_default_token( 520 );
get_order_tokens( $order_id )
订单可以关联支付令牌(例如,用于订阅产品和续费)。 您可以使用此函数获取关联的令牌列表。 另外,您还可以使用 WC_Order 的 get_payment_tokens() 函数来获得相同的结果。
// 获取与订单 25 关联的支付令牌
$tokens = WC_Payment_Tokens::get_order_tokens( 25 );
// 通过 WC_Order 获取与订单 25 关联的支付令牌
$order = wc_get_order( 25 );
$tokens = $order->get_payment_tokens();
get( $token_id )
返回由提供的 $token_id 指定的单个支付令牌对象。
// 获取支付令牌 52
$token = WC_Payment_Tokens::get( 52 );
delete( $token_id )
删除提供的令牌。
// 删除支付令牌 52
WC_Payment_Tokens::delete( 52 );
set_users_default( $user_id, $token_id )
将提供的令牌 ($token_id) 设置为提供的用户 ($user_id) 的默认令牌。 它会移除当前设置为默认的令牌,并设置新的令牌。
// 将用户 17 的默认令牌设置为令牌 82
WC_Payment_Tokens::set_users_default( 17, 82 );
get_token_type_by_id( $token_id )
如果您知道令牌的 ID,但不知道它的类型(信用卡、电子支票等),可以使用此函数。
// 确定支付令牌 23 是信用卡令牌
$type = WC_Payment_Tokens::get_token_type_by_id( 23 );
WC_Payment_Token_CC
set_ 方法不会更新数据库中的令牌。 您必须调用 save()、create()(仅用于新令牌)或 update()(仅用于现有令牌)。
validate()
确保信用卡令牌存储了后 4 位数字,有效期年份的格式为 YYYY,有效期月份的格式为 MM,卡类型以及实际的令牌。
$token = new WC_Payment_Token_CC();
$token->set_token( 'token here' );
$token->set_last4( '4124' );
$token->set_expiry_year( '2017' );
$token->set_expiry_month( '1' ); // 长度不正确
$token->set_card_type( 'visa' );
var_dump( $token->validate() ); // bool(false)
$token->set_expiry_month( '01' );
var_dump( $token->validate() ); // bool(true)
get_card_type()
获取卡类型(visa、mastercard 等)。
$token = WC_Payment_Tokens::get( 42 );
echo $token->get_card_type();
set_card_type( $type )
设置信用卡类型。这是一个自由格式的文本字段,但可以使用以下值,WooCommerce 将显示格式化的标签。可以通过 woocommerce_credit_card_type_labels 过滤器添加新的标签。
$token = WC_Payment_Tokens::get( 42 );
$token->set_last4( 'visa' );
echo $token->get_card_type(); // 返回 visa
支持的类型/标签:
array(
'mastercard' => __( 'MasterCard', 'woocommerce' ),
'visa' => __( 'Visa', 'woocommerce' ),
'discover' => __( 'Discover', 'woocommerce' ),
'american express' => __( 'American Express', 'woocommerce' ),
'diners' => __( 'Diners', 'woocommerce' ),
'jcb' => __( 'JCB', 'woocommerce' ),
) );
get_expiry_year()
获取信用卡的到期年份。
$token = WC_Payment_Tokens::get( 42 );
echo $token->get_expiry_year;
set_expiry_year( $year )
设置信用卡的到期年份。格式为 YYYY。
$token = WC_Payment_Tokens::get( 42 );
$token->set_expiry_year( '2018' );
echo $token->get_expiry_year(); // 返回 2018
get_expiry_month()
获取信用卡的到期月份。
$token = WC_Payment_Tokens::get( 42 );
echo $token->get_expiry_month();
set_expiry_month( $month )
设置信用卡的到期月份。格式为 MM。
$token = WC_Payment_Tokens::get( 42 );
$token->set_expiry_year( '12' );
echo $token->get_expiry_month(); // 返回 12
get_last4()
获取存储的信用卡号码的后 4 位数字。
$token = WC_Payment_Tokens::get( 42 );
echo $token->get_last4();
set_last4( $last4 )
设置存储的信用卡号码的后 4 位数字。
$token = WC_Payment_Tokens::get( 42 );
$token->set_last4( '2929' );
echo $token->get_last4(); // 返回 2929
WC_Payment_Token_eCheck
set_ 方法不会更新数据库中的令牌。您必须调用 save()、create()(仅适用于新令牌)或 update()(仅适用于现有令牌)。
validate()
确保 eCheck 令牌存储了后 4 位数字以及实际的令牌。
$token = new WC_Payment_Token_eCheck();
$token->set_token( 'token here' );
var_dump( $token->validate() ); // bool(false)
$token->set_last4( '4123' );
var_dump( $token->validate() ); // bool(true)
get_last4()
获取存储的账户号码的后 4 位数字。
$token = WC_Payment_Tokens::get( 42 );
echo $token->get_last4();
set_last4( $last4 )
设置存储的信用卡号码的后 4 位数字。
$token = WC_Payment_Tokens::get( 42 );
$token->set_last4( '2929' );
echo $token->get_last4(); // 返回 2929
WC_Payment_Token
您不应该直接使用 WC_Payment_Token 类。请使用其中一个内置的令牌类 (WC_Payment_Token_CC 用于信用卡,WC_Payment_Token_eCheck 用于电子支票)。 如果上述方法都不适用于您,您可以扩展此类。 此部分中定义的所有方法都可供这些类使用。
set_ 方法不会更新数据库中的令牌。 您必须调用 save() (保存),create() (仅用于创建新令牌),或 update() (仅用于更新现有令牌)。
get_id()
获取令牌的 ID。
// 获取用户 ID 为 26 的默认令牌的 ID
$token = WC_Payment_Tokens::get_customer_default_token( 26 );
echo $token->get_id();
get_token()
获取实际的令牌字符串(用于与支付处理商通信)。
$token = WC_Payment_Tokens::get( 49 );
echo $token->get_token();
set_token( $token )
设置令牌字符串。
// $api_token 来自向支付处理商的 API 请求。
$token = WC_Payment_Tokens::get( 42 );
$token->set_token( $api_token );
echo $token->get_token(); // 返回我们的令牌
get_type()
获取令牌的类型。可以是 CC(信用卡)或 eCheck(电子支票)。 这也会返回任何新引入的类型。
$token = WC_Payment_Tokens::get( 49 );
echo $token->get_type();
get_user_id()
获取与令牌关联的用户 ID。
$token = WC_Payment_Tokens::get( 49 );
if ( $token->get_user_id() === get_current_user_id() ) {
// 此令牌属于当前用户。
}
set_user_id( $user_id )
将令牌与用户关联。
$token = WC_Payment_Tokens::get( 42 );
$token->set_user_id( '21' ); // 此令牌现在属于用户 21。
echo $token->get_last4(); // 返回 2929
get_gateway_id
获取与令牌关联的网关。
$token = WC_Payment_Tokens::get( 49 );
$token->get_gateway_id();
set_gateway_id( $gateway_id )
设置与令牌关联的网关。 这应该与您网关中定义的 "ID" 匹配。 例如,'simplify_commerce' 是核心中 Simplify 实现的 ID。
$token->set_gateway_id( 'simplify_commerce' );
echo $token->get_gateway_id();
is_default()
如果令牌被标记为用户的默认令牌,则返回 true。 默认令牌将在结账时自动选择。
$token = WC_Payment_Tokens::get( 42 ); // 令牌 42 是用户 3 的默认令牌
var_dump( $token->is_default() ); // 返回 true
$token = WC_Payment_Tokens::get( 43 ); // 令牌 43 是用户 3 的令牌,但不是默认的
var_dump( $token->is_default() ); // 返回 false
set_default( $is_default )
切换一个令牌的“默认”标志。 传递 true 将其设置为默认值,如果它只是另一个令牌,则传递 false。 这不会取消设置任何其他可能设置为默认值的令牌。 您可以使用 WC_Payment_Tokens::set_users_default() 来处理这种情况。
$token = WC_Payment_Tokens::get( 42 ); // 令牌 42 是用户 3 的默认令牌
var_dump( $token->is_default() ); // 返回 true
$token->set_default( false );
var_dump( $token->is_default() ); // 返回 false
validate()
进行检查,以确保令牌和令牌类型(信用卡、电子支票等)都存在。 请参阅 WC_Payment_Token_CC::validate() 或 WC_Payment_Token_eCheck::validate() 以了解用法。
read( $token_id )
从数据库加载现有的令牌对象。 请参阅 WC_Payment_Tokens::get(),它是此函数的别名。
// 加载信用卡令牌,ID 为 55,用户 ID 为 5
$token = WC_Payment_Token_CC();
$token->read( 55 );
echo $token->get_id(); // 返回 55
echo $token->get_user_id(); // 返回 5
update()
更新现有的令牌。 这将获取所有更改的字段(set_ 函数),并将它们实际保存到数据库中。 返回 true 或 false,具体取决于是否成功。
$token = WC_Payment_Tokens::get( 42 ); // 信用卡令牌
$token->set_expiry_year( '2020' );
$token->set_expiry_month( '06 ');
$token->update();
create()
这将创建一个新的令牌到数据库中。 因此,一旦您构建了它,create() 将在数据库中创建一个新的令牌,其中包含详细信息。 返回 true 或 false,具体取决于是否成功。
$token = new WC_Payment_Token_CC();
// 设置 last4、到期年份、月份和卡类型
$token->create(); // 保存到数据库
save()
save() 可以替代 update() 和 create()。 如果您正在处理现有的令牌,则 save() 将调用 update()。 新的令牌将调用 create()。 返回 true 或 false,具体取决于是否成功。
// 调用 update
$token = WC_Payment_Tokens::get( 42 ); // 信用卡令牌
$token->set_expiry_year( '2020' );
$token->set_expiry_month( '06 ');
$token->save();
// 调用 create
$token = new WC_Payment_Token_CC();
// 设置 last4、到期年份、月份和卡类型
$token->save();
delete()
从数据库中删除一个令牌。
$token = WC_Payment_Tokens::get( 42 );
$token->delete();
配送方法 API
WooCommerce 提供了配送方法 API,插件可以使用它来添加自己的费率。本文将引导您完成创建基于核心统一费率方法的新的配送方法,并与配送 API 交互的步骤。
创建一个插件
首先,创建一个标准的 WordPress/WooCommerce 插件 - 请参考我们的 [构建您的第一个扩展](docs/features/shipping/ /docs/extensions/getting-started-extensions/building-your-first-extension) 教程,以开始。您将在该插件文件中定义您的配送方法类,并在 WooCommerce 之外维护它。
检查 WooCommerce 并创建一个函数来存放您的类
在尝试加载我们的类之前,我们需要确保 WooCommerce 已启用,并且我们工作所需的必要类和函数是可用的。一旦我们知道这些是可用的,我们就可以添加一个动作来初始化我们的类,并添加一个过滤器,将我们的方法添加到主要的配送方法列表中。
/**
* 如果 WooCommerce 已启用,则这些类和函数将存在。
*/
if ( class_exists( 'woocommerce' ) && class_exists( 'WC_Shipping_Method' ) && function_exists( 'WC' ) ) {
// 我们添加一个动作来初始化我们的配送方法类,并添加一个过滤器,将我们的配送方法添加到方法列表中。
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
add_filter( 'woocommerce_shipping_methods', 'your_shipping_method_add' );
}
/**
* 您的函数,用于将您的配送方法添加到配送方法列表中。
*/
function your_shipping_method_add( $methods ) {
$methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
return $methods;
}
/**
* 您的函数,用于初始化您的配送方法类。
*/
function your_shipping_method_init() {
// 您的类将放在这里
}
创建您的类
现在,我们创建一个类,将其放置在刚刚创建的函数内部。 最好确保该类不存在,以避免出现意外的致命错误。 该类需要继承 Shipping Method 类,以便我们能够访问 Shipping 和 Settings API。 我们还确保声明必要的属性,然后在构造函数中定义更多选项/属性,最后调用 init 方法。
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
class WC_Your_Shipping_Method extends WC_Shipping_Method {
/**
* 配送类型成本。
*
* @var string
*/
public $cost;
/**
* 配送类型。
*
* @var string
*/
public $type;
/**
* 您的配送类构造函数。
*
* @param int $instance_id 配送类型实例 ID。 每次在配送区域中创建实例时,都会分配一个新的实例 ID。
* @return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'your_shipping_method'; // 您的配送类型 ID。 应该唯一。
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Your Shipping Method', 'your_text_domain' ); // 在管理员界面中显示的标题。
$this->method_description = __( 'Description of your shipping method', 'your_text_domain' ); // 在管理员界面中显示的描述。
$this->supports = array(
'settings', // 提供一个独立的设置选项卡,该选项卡位于 WooCommerce > 设置 > 配送 区域下,用于您的配送类型。
'shipping-zones', // 允许商家将您的配送类型添加到配送区域。
'instance-settings', // 允许一个页面,供商家编辑包含在配送区域中的您的配送类型的实例。
'instance-settings-modal', // 允许一个模态框,供商家编辑包含在配送区域中的您的配送类型的实例。
);
// 配送类型的附加初始化。
$this->init();
}
}
}
定义设置/选项
为了确保在选项更新时,对配送方法添加一个动作,调用 process_admin_options 函数,以便保存管理员/商家选择保存时输入的任何设置。
然后,可以使用 WooCommerce 设置 API 定义选项。 我们有两个额外的 Method,init_form_fields 和 init_instance_form_fields,它们将分别初始化独立设置和实例设置的表单字段。 其他选项,例如标题、税收状态等,通过设置 API 的 get_option Method 进行设置。 这些设置适用于独立的 Page,或者实例设置,具体取决于当前正在 Display 的内容。
/**
* 配送方法选项的附加初始化,在构造函数中通常是不必要的。
*
* @return void
*/
public function init() {
// 如果已定义任何设置,则在管理员界面中保存设置。(使用配送/设置 API)
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
// 初始化独立的设置和实例设置的表单字段。
$this->init_form_fields();
$this->init_instance_form_fields();
// 使用设置 API 获取已保存的选项,用于设置字段。
$this->title = $this->get_option( 'title' );
$this->tax_status = $this->get_option( 'tax_status' );
$this->cost = $this->get_option( 'cost' );
$this->type = $this->get_option( 'type', 'class' );
}
# 设置页面表单字段初始化
/**
* 用于初始化独立设置页面的表单字段,如果需要。
*
* @return void
*/
public function init_form_fields() {
// 将 `form_fields` 属性设置为一个数组,该数组可供设置 API 在页面上显示字段。
$this->form_fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true, // 如果希望将描述显示为工具提示,则包含此项。
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'placeholder' => '',
'description' => __( '请输入费用(不含税)。', 'your_text_domain' ),
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
}
/**
* 用于初始化独立实例的表单字段。
*
* @return void
*/
private function init_instance_form_fields() {
// 定义一些字符串,这些字符串将多次用于费用描述和链接。
$cost_desc = __( '请输入费用(不含税)。', 'your_text_domain' );
$cost_link = sprintf( '<span id="wc-shipping-advanced-costs-help-text">%s <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#advanced-costs">%s</a>.</span>', __( '按件收取统一费率,或输入费用公式,以按百分比收取费用,或收取最低费用。 了解更多关于', 'your_text_domain' ), __( '高级费用', 'your_text_domain' ) );
}
统一费率配送设置
// 开始定义字段数组。
$fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true,
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => '',
'description' => $cost_desc,
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
/**
* 统一费率配送可以按配送类型添加费用,因此这里获取配送类型,并提供字段供商家/管理员使用,以便他们可以指定这些费用。
*/
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
$fields['class_costs'] = array(
'title' => __( '按配送类型划分的费用', 'your_text_domain' ),
'type' => 'title',
'default' => '',
/* 译者: %s: 链接的 URL */
'description' => sprintf( __( '这些费用可以选择性地根据 <a target="_blank" href="%s">产品配送类型</a> 添加。 了解更多关于 <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#shipping-classes">设置配送类型费用</a> 的信息。', 'your_text_domain' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ),
);
foreach ( $shipping_classes as $shipping_class ) {
if ( ! isset( $shipping_class->term_id ) ) {
continue;
}
$fields[ 'class_cost_' . $shipping_class->term_id ] = array(
/* 译者: %s: 配送类型名称 */
'title' => sprintf( __( '"%s" 配送类型的费用', 'your_text_domain' ), esc_html( $shipping_class->name ) ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ),
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
}
}
说明:
- 配送类型: Shipping Classes
- 配送类型: Shipping Class
- 设置: Settings
- 状态: Status
- 链接: Link
- 别名: Slug
- 网页: Page
- 占位符: Placeholder
- 译者: Translators
- 类名: Class name
- 客户: Customers
- 统一费率: Flat Rate
- 继续: Continue
- 文档: document
- 配送: Shipping
- 结账: Checkout
- 部分: Section
- 产品: Product
- 字段: Fields
- 选择: Select
# 配送类型配置
本节描述如何配置配送类型。
**使用**以下步骤配置配送类型:
1. **选择**“配送类型”选项。
2. **选择**“添加新类型”按钮。
3. **在**“标题”字段中输入配送类型的名称。
4. **在**“描述”字段中输入配送类型的描述。
5. **选择**“启用”复选框以启用配送类型。
6. **单击**“更新”按钮保存更改。
以下是可用的字段:
* `no_class_cost`: 无配送类型费用。
* `type`: 计算类型。
以下是每个字段的详细信息:
## 字段描述
```php
$fields['no_class_cost'] = array(
'title' => __( 'No shipping class cost', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => '',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
$fields['type'] = array(
'title' => __( 'Calculation type', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'class',
'options' => array(
'class' => __( 'Per class: Charge shipping for each shipping class individually', 'your_text_domain' ),
'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'your_text_domain' ),
),
'description' => $cost_link,
);
}
// And finally we set the instance_form_fields property for the Shipping API to use.
$this->instance_form_fields = $fields;
}
no_class_cost: 无配送类型费用。
type: 计算类型。
class: 按配送类型:为每个配送类型单独收取运费。order: 按订单:收取最昂贵的配送类型的运费。
最后,我们设置 instance_form_fields 属性,以便 Shipping API 使用。
## 清理成本
在前面的代码片段中,您可以看到有一个 `sanitize_callback` 用于 `sanitize_cost`,虽然这可能并不总是需要,但始终牢记清理用户输入仍然是一个好习惯。由于成本字段需要是一个文本字段才能允许使用十进制分隔符,因此我们需要确保输入的值是有效的。为此,我们引入了以下方法。
```php
/**
* 清理成本值。
* 当 `sanitize_callback` 方法在 Settings API 中被调用时,此方法会被调用,用于保存商家输入的值。
*
* @param string $value 未清理的值。
* @return string
* @throws Exception 如果成本不是数值。
*/
public function sanitize_cost( $value ) {
// 如果值为空,则将其设置为零。对值运行 WordPress 核心的清理函数,然后移除货币符号,如果存在。
$value = is_null( $value ) ? '0' : $value;
$value = wp_kses_post( trim( wp_unslash( $value ) ) );
$value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value );
// 获取当前区域设置以及所有可能的十进制分隔符。
$locale = localeconv();
$decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' );
// 移除空格,然后移除十进制分隔符,然后移除无效的起始/结束字符。
$value = preg_replace( '/\s+/', '', $value );
$value = str_replace( $decimals, '.', $value );
$value = rtrim( ltrim( $value, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" );
// 如果值不是数值,则抛出异常。
if ( ! is_numeric( $value ) ) {
throw new Exception( 'Invalid cost entered.' );
}
return $value;
}
添加运费
运费通过 Shipping API 使用 add_rate 方法添加。以下是可用选项的分解,在下一部分我们将将其应用到实际中。
您的配送方法可以传递任意数量的运费,只需确保每个运费的 ID 都是不同的。 用户可以在结账时选择运费。
$rate = array(
'label' => '', // 运费的标签。
'cost' => '0', // 运费金额,或用于每个商品的运费的费用数组。
'taxes' => '', // 传递一个税费数组,或者不传递任何内容以让系统自动计算,或者传递 'false' 以表示此方法不计算税费。
'calc_tax' => 'per_order' // 按订单计算税费 (per_order) 或按商品计算税费 (per_item)。 按商品计算需要通过 'cost' 传递一个费用数组。
);
// 注册运费
$this->add_rate( $rate );
calculate_shipping() 方法
用于添加费率的方法是 calculate_shipping。当 WooCommerce 在购物车和结账过程中进行配送计算时,会调用此方法。在此处进行插件特定的计算,然后通过配送 API 添加费率。
我们还包含 find_shipping_classes 方法,该方法从每个包裹中的商品获取配送类型。
/**
* 计算配送成本。
*
* @param array $package 购物车中的商品包裹。
*/
public function calculate_shipping( $package = array() ) {
// 获取此实例的费率设置。
$rate = array(
'id' => $this->get_rate_id(), // 从配送 API 获取实例费率 ID。
'label' => $this->title,
'cost' => 0,
'package' => $package,
);
// 计算成本。
$has_costs = false; // 如果设置了成本,则为 true。如果所有成本为空字符串,则为 false。
$cost = $this->get_option( 'cost' );
// 如果设置了成本,则评估成本以确保其有效。
if ( '' !== $cost ) {
$has_costs = true;
$rate['cost'] = $cost;
}
// 统一费率具有为每个配送类型设置成本的能力,因此,这里获取配送类型,并添加相应的成本。
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
// 检查购物车/包裹中的产品是否已分配了配送类型。
$found_shipping_classes = $this->find_shipping_classes( $package );
$highest_class_cost = 0;
// 如果发现产品已分配了配送类型,则遍历每个配送类型。
foreach ( $found_shipping_classes as $shipping_class => $products ) {
// 同时也处理向后兼容性,即使用别名而不是 ID 的情况。
$shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' );
$class_cost = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' );
// 如果未为配送类型分配成本,则跳过该配送类型。
if ( '' === $class_cost ) {
continue;
}
// 我们有一个配送类型成本,因此,评估该类成本以确认其有效。
$has_costs = true;
/**
* 统一费率在配送类型方面有两种选择:按类或按订单。
* 这里检查该设置,以便相应地应用成本。
*/
if ( 'class' === $this->type ) {
$rate['cost'] += $class_cost;
} else {
$highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost;
}
}
// 如果成本是按订单计算的,则将最高的类成本应用于基本成本。
if ( 'order' === $this->type && $highest_class_cost ) {
$rate['cost'] += $highest_class_cost;
}
}
配送类型相关功能
以下代码片段展示了与配送类型相关的实现。
if ( $has_costs ) {
$this->add_rate( $rate );
}
/**
* 开发者可以通过以下动作,基于此统一费率添加额外的费率,自 @version 2.4 起。
*
* 之前存在(过于复杂)的选项来添加额外的费率,但这些选项不够用户友好,并且与统一费率配送的最初意图相悖。
*/
do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
}
/**
* 查找并返回配送类型以及具有该配送类型的产品。
*
* @param mixed $package 购物车中的项目集合。
* @return array
*/
public function find_shipping_classes( $package ) {
$found_shipping_classes = array();
foreach ( $package['contents'] as $item_id => $values ) {
if ( $values['data']->needs_shipping() ) {
$found_class = $values['data']->get_shipping_class();
if ( ! isset( $found_shipping_classes[ $found_class ] ) ) {
$found_shipping_classes[ $found_class ] = array();
}
$found_shipping_classes[ $found_class ][ $item_id ] = $values;
}
}
return $found_shipping_classes;
}
说明:
Shipping Classes译为配送类型Shipping Class译为配送类型Version 2.4译为版本 2.4Developers译为开发者Flat Rate译为统一费率Version译为版本Contents译为内容Shipping译为配送Product译为产品Option译为选项Rates译为费率Value译为价值Mixed译为混合Class译为类Data译为数据Cart译为购物车Item译为项目Find译为查找Via译为通过
整合所有内容
我们精简后的统一费率配送方法独立插件的代码如下:
<?php
/**
* 插件名称: Your Shipping 插件
* 插件 URI: https://woocommerce.com/
* 描述: Your shipping 方法插件
* 版本: 1.0.0
* 作者:WooCommerce
* 作者 URI: https://woocommerce.com/
* Text Domain: your_text_domain
*/
/**
* 如果 WooCommerce 处于激活状态,则该类将存在。
*/
if ( class_exists( 'woocommerce' ) && class_exists( 'WC_Shipping_Method' ) && function_exists( 'WC' ) ) {
// 我们添加一个动作来初始化我们的配送方法类,并添加一个过滤器来将我们的配送方法添加到方法列表中。
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
add_filter( 'woocommerce_shipping_methods', 'your_shipping_method_add' );
}
/**
* 您的函数,用于将您的配送方法添加到配送方法列表中。
*/
function your_shipping_method_add( $methods ) {
$methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
return $methods;
}
/**
* 您的函数,用于初始化您的配送方法类。
*/
function your_shipping_method_init() {
/**
* 理想情况下,这应该从另一个文件中包含该类,但为了演示目的,我们将在其中包含它。
*/
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
class WC_Your_Shipping_Method extends WC_Shipping_Method {
/**
* 配送方法成本。
*
* @var string
*/
public $cost;
/**
* 配送方法类型。
*
* @var string
*/
public $type;
/**
* 您的配送类型的构造函数。
*
* @param int $instance_id 配送方法实例 ID。每次在配送区域中创建实例时,都会分配一个新的实例 ID。
* @return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'your_shipping_method'; // 您的配送方法的 ID。应该唯一。
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Your Shipping Method', 'your_text_domain' ); // 在管理员界面中显示的标题。
$this->method_description = __( 'Description of your shipping method', 'your_text_domain' ); // 在管理员界面中显示的描述。
$this->supports = array(
'settings', // 提供一个独立的设置选项卡,位于 WooCommerce > 设置 > 配送。
'shipping-zones', // 允许商家将您的配送方法添加到配送区域。
'instance-settings', // 允许一个页面,供商家编辑包含在配送区域中的您的方法的实例。
'instance-settings-modal', // 允许一个模态框,供商家编辑包含在配送区域中的您的方法的实例。
);
// 配送方法的其他初始化。
$this->init();
}
/**
* 额外的选项初始化,这些选项在构造函数中不需要进行初始化。
*
* @return void
*/
public function init() {
// 如果定义了任何设置,则在后台保存设置。(使用配送/设置 API)
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
// 初始化独立的设置,以及实例设置的表单字段。
$this->init_form_fields();
$this->init_instance_form_fields();
// 使用设置 API 获取已保存的选项,用于设置字段。
$this->title = $this->get_option( 'title' );
$this->tax_status = $this->get_option( 'tax_status' );
$this->cost = $this->get_option( 'cost' );
$this->type = $this->get_option( 'type', 'class' );
}
/**
* 计算配送成本。
*
* @param array $package 购物车中的商品包。
*/
public function calculate_shipping( $package = array() ) {
// 获取此实例的费率。
$rate = array(
'id' => $this->get_rate_id(), // 从配送 API 获取实例费率 ID。
'label' => $this->title,
'cost' => 0,
'package' => $package,
);
// 计算成本。
$has_costs = false; // 如果设置了成本,则为 true。如果所有成本为空字符串,则为 false。
$cost = $this->get_option( 'cost' );
// 如果设置了成本,则评估成本以确保其有效。
if ( '' !== $cost ) {
$has_costs = true;
$rate['cost'] = $cost;
}
// 统一费率配送具有为每个配送类型设置成本的能力,因此这里获取配送类型,并添加这些成本。
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
// 检查购物车/包中的产品是否已分配了配送类型。
$found_shipping_classes = $this->find_shipping_classes( $package );
$highest_class_cost = 0;
// 如果发现产品已分配了配送类型,则遍历每个配送类型。
foreach ( $found_shipping_classes as $shipping_class => $products ) {
// 同时也处理向后兼容性,当使用别名而不是 ID 时。
$shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' );
$class_cost = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' );
// 如果未为配送类型分配成本,则跳到下一个类型。
if ( '' === $class_cost ) {
continue;
}
// 我们有一个配送类型成本,因此评估该类成本以确认其有效。
$has_costs = true;
统一费率计算逻辑
/**
- 统一费率有两种选项,当涉及到配送类型时,可以按配送类型计算,也可以按订单计算。
- 这里我们检查该设置,以便相应地应用成本。 */ if ( 'class' === $this->type ) { $rate['cost'] += $class_cost; } else { $highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost; }
// 如果成本是按订单计算的,那么我们将最高的配送类型成本应用到基础成本上。 if ( 'order' === $this->type && $highest_class_cost ) { $rate['cost'] += $highest_class_cost; }
if ( $has_costs ) { $this->add_rate( $rate ); }
/**
- 开发者可以通过此操作钩子,基于此统一费率添加额外的费率,自 @version 2.4 起。
- 之前有一些(过于复杂)的选项可以添加额外的费率,但这些选项不方便用户使用,并且违背了统一费率配送的原始意图。 */ do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
/**
-
查找并返回配送类型以及具有该配送类型的产品。
-
@param mixed $package 购物车中的商品包。
-
@return array */ public function find_shipping_classes( $package ) { $found_shipping_classes = array();
foreach ( $package['contents'] as $item_id => $values ) { if ( $values['data']->needs_shipping() ) { $found_class = $values['data']->get_shipping_class();
if ( ! isset( $found_shipping_classes[ $found_class ] ) ) { $found_shipping_classes[ $found_class ] = array(); } $found_shipping_classes[ $found_class ][ $item_id ] = $values; }}
return $found_shipping_classes; }
/**
-
净化成本值。
-
此方法在
Settings API中调用sanitize_callback方法时被调用,用于保存商家输入的值。 -
@param string $value 未净化的值。
-
@return string
-
@throws Exception 如果成本不是数值。 */ public function sanitize_cost( $value ) { // 如果值为空,则将其设置为零。 将值通过 WordPress 核心的净化函数,然后移除货币符号,如果存在。 $value = is_null( $value ) ? '0' : $value; $value = wp_kses_post( trim( wp_unslash( $value ) ) ); $value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value );
// 获取当前区域设置以及所有可能的十进制分隔符。 $locale = localeconv(); $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' ); }
设置
本页面描述了如何配置插件的各种设置。
设置
- Settings → 设置
- Status → 状态
- String → 字符串
- Link → 链接
- Page → 网页
- API → API
- Tag → 标签
- Settings Page → 设置页面
- Placeholder → 占位符
- Form fields → 表单字段
- Percentage → 百分比
- characters → 字符
- Customers → 客户
- Flat Rate → 统一费率
- document → 文档
- Property → 属性
- Shipping → 配送
- Checkout → 结账
- Minimum → 最小
- Replace → 替换
// Remove whitespace, then decimals, and then invalid start/end characters.
$value = preg_replace( '/\s+/', '', $value );
$value = str_replace( $decimals, '.', $value );
$value = rtrim( ltrim( $value, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" );
// If the value is not numeric, then throw an exception.
if ( ! is_numeric( $value ) ) {
throw new Exception( 'Invalid cost entered.' );
}
return $value;
}
/**
* Our method to initialize our form fields for our stand alone settings page, if needed.
*
* @return void
*/
public function init_form_fields() {
// Set the form_fields property to an array that will be able to be used by the Settings API to show the fields on the page.
$this->form_fields = array(
'title' => array(
'title' => __( 'Name', 'your_text_domain' ),
'type' => 'text',
'description' => __( 'Your customers will see the name of this shipping method during checkout.', 'your_text_domain' ),
'default' => __( 'Your shipping method', 'your_text_domain' ),
'placeholder' => __( 'e.g. Standard national', 'your_text_domain' ),
'desc_tip' => true, // Include this if you would like your description to show as a tooltip.
),
'tax_status' => array(
'title' => __( 'Tax status', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( 'Taxable', 'your_text_domain' ),
'none' => _x( 'None', 'Tax status', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( 'Cost', 'your_text_domain' ),
'type' => 'text',
'placeholder' => '',
'description' => __( 'Enter a cost (excl. tax).', 'your_text_domain' ),
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
}
/**
* Our method to initialize our form fields for separate instances.
*
* @return void
*/
private function init_instance_form_fields() {
// Define some strings that will be used several times for the cost description and link.
$cost_desc = __( 'Enter a cost (excl. tax).', 'your_text_domain' );
$cost_link = sprintf( '<span id="wc-shipping-advanced-costs-help-text">%s <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#advanced-costs">%s</a>.</span>', __( 'Charge a flat rate per item, or enter a cost formula to charge a percentage based cost or a minimum fee. Learn more about', 'your_text_domain' ), __( 'advanced costs', 'your_text_domain' ) );
设置页面 允许您配置插件的各种选项。
- 名称 (Name): 名称 字段允许您为该配送方法设置一个名称。 您的客户将在结账过程中看到此名称。 占位符:例如,标准国内。
- 税收状态 (Tax status): 税收状态 字段允许您指定该配送方法是否应收取税费。
- 成本 (Cost): 成本 字段允许您输入一个统一费率。
您还可以使用链接访问更多信息。
统一费率配送设置
// 开始定义字段数组。
$fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true,
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => '',
'description' => $cost_desc,
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
/**
* 统一费率配送可以按配送类型添加费用,因此这里获取配送类型,并提供字段供商家/管理员使用,以便他们可以指定这些费用。
*/
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
$fields['class_costs'] = array(
'title' => __( '按配送类型划分的费用', 'your_text_domain' ),
'type' => 'title',
'default' => '',
/* 译: %s: 链接的 URL */
'description' => sprintf( __( '这些费用可以选择性地根据 <a target="_blank" href="%s">产品的配送类型</a> 添加。 了解更多关于 <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#shipping-classes">设置配送类型费用</a> 的信息。', 'your_text_domain' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ),
);
foreach ( $shipping_classes as $shipping_class ) {
if ( ! isset( $shipping_class->term_id ) ) {
continue;
}
$fields[ 'class_cost_' . $shipping_class->term_id ] = array(
/* 译: %s: 配送类型名称 */
'title' => sprintf( __( '"%s" 配送类型的费用', 'your_text_domain' ), esc_html( $shipping_class->name ) ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ),
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
}
配送类型
设置
状态
链接
别名
网页
占位符
译:
类名
客户
统一费率
继续
document
配送
结账
部分
产品
字段
选择
# 配送类型配置
本页面允许您配置配送类型相关的设置。
**字段说明:**
* `no_class_cost`:
* `title`: "无配送类型费用"
* `type`: 文本
* `class`: `wc-shipping-modal-price`
* `placeholder`: "无"
* `description`: `$cost_desc`
* `default`: ""
* `desc_tip`: `true`
* `sanitize_callback`: `array( $this, 'sanitize_cost' )`
* `type`:
* `title`: "计算类型"
* `type`: `Select`
* `class`: `wc-enhanced-select`
* `default`: `class`
* `options`:
* `class`: "按配送类型:为每个配送类型单独收取配送费用"
* `order`: "按订单:为最贵的配送类型收取配送费用"
* `description`: `$cost_link`
**使用方法:**
1. 请根据您的需求配置各个`字段`。
2. `Select`框中,您可以`选择`合适的`选项`。
3. `Placeholder`占位符提示您输入内容。
**注意事项:**
* `API`接口可能需要特定的配置。
* `Property`的设置会影响`Shipping`的计算结果。
* 如果遇到问题,请参考`链接`中的文档。
* `Order`的计算方式会影响最终的费用。
* `Older`版本的插件可能存在兼容性问题。
* `Class`的定义决定了`Shipping`的分类。
* `and`操作符用于组合条件。
* `For`循环用于重复执行操作。
* `n/a`表示“无”。
* `Tan`表示“褐色”。
* `In`表示“在”。
* `No`表示“否”。
$fields['no_class_cost'] = array( 'title' => __( 'No shipping class cost', 'your_text_domain' ), 'type' => 'text', 'class' => 'wc-shipping-modal-price', 'placeholder' => __( 'N/A', 'your_text_domain' ), 'description' => $cost_desc, 'default' => '', 'desc_tip' => true, 'sanitize_callback' => array( $this, 'sanitize_cost' ), );
$fields['type'] = array(
'title' => __( 'Calculation type', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'class',
'options' => array(
'class' => __( 'Per class: Charge shipping for each shipping class individually', 'your_text_domain' ),
'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'your_text_domain' ),
),
'description' => $cost_link,
);
}
// And finally we set the instance_form_fields property for the Shipping API to use.
$this->instance_form_fields = $fields;
}
}
}
}
AI
本指南提供了关于 AI 工具的概述,以及如何使用它们来增强您的 WooCommerce 开发工作流程。
MCP
WooCommerce 内置了对模型上下文协议 (MCP) 的支持,这使得 AI 助手和工具能够通过标准协议直接与 WooCommerce 商店进行交互。请访问我们的完整 MCP 文档 以获取更多信息。
AI 文档工具
LLMS.txt 文件
为了将 WooCommerce 开发者文档导入到您的 LLM 或 AI 辅助 IDE 中,您有两种选择:
llms.txt- 包含每个文档的标题、URL 和描述的目录。llms-full.txt- 整个文档的完整 Markdown 格式导出,包含在一个文件中。
如果您使用的是 Cursor 或 Windsurf 等 IDE,我们建议将这些链接添加到自定义文档中,以便根据需要进行引用。
注意:这些文件不包含 WC REST API 文档 或 WooCommerce 代码参考 的内容。
以 Markdown 格式查看
如果您想以 Markdown 文件的形式查看文档,可以将 .md 添加到任何文档 URL 的末尾。例如,要以 Markdown 格式查看此页面,您可以访问:
https://developer.woocommerce.com/docs/getting-started/ai.md
复制为 Markdown
在开发者文档的每个页面,您会在右上角看到一个剪贴板图标。选择此图标会将当前文档以 Markdown 格式复制,您可以将其粘贴到 LLM 的聊天界面中。
AI 开发工具
贡献者的 Agent Skills
WooCommerce 单一仓库包含 agent skills,为 AI 助手提供有关常见开发任务的流程指导。这些技能位于仓库根目录下的 .ai/skills/ 目录中。
每个技能都包含一个 SKILL.md 文件,其中包含有关以下任务的逐步说明:
- 后端 PHP 开发和测试规范
- 代码审查标准和最佳实践
- Git 工作流程和提交规范
- 构建和 linting 过程
- UI 文本和文档指南
这些技能的设计是工具无关的,可以与各种 AI 编码助手一起使用。要探索可用的技能,请浏览仓库中的 .ai/skills/ 目录。
贡献者的 Cursor Rules 文件
.cursor/rules/ 目录包含配置文件,这些文件为 AI 助手提供有关如何处理 WooCommerce 代码库的特定指导。这些文件有助于确保一致的开发实践和工作流程。
调试资源
WordPress
通常,一个好的起点是 WordPress 本身内置的调试工具:
Debugging in WordPress 文档 涵盖了许多您可以设置的环境变量,以启用 WordPress 的核心调试工具。
Query Monitor
一个流行的 WordPress 开发者插件是 Query Monitor,它是 WordPress 的开发者工具。Query Monitor 允许您调试数据库查询、PHP 错误、AJAX/Rest 请求、钩子和操作、块编辑器块、已加载的脚本和样式表、HTTP API 调用等等。
邮件调试
在本地 WooCommerce 环境中工作时,我们建议启用 Mailpit 或 Mailhog 等工具,将所有事务性邮件重定向到日志,而不是发送出去。
或者,您可以使用 Stop Emails 等插件来禁用任何意外的邮件触发。
WooCommerce
日志记录
WooCommerce 具有一个日志记录系统,对于查找和跟踪网站上的错误非常有用:
即将推出模式
WooCommerce 的“即将推出”模式允许您在您进行开发时,暂时使您的网站对公众不可见。
PHP/JavaScript 调试
Xdebug
如果您使用 wp-env 运行本地开发环境(这是 WooCommerce monorepo 的推荐方法),您可以激活 Xdebug,然后使用 VS Code 或 PhpStorm 等 IDE 来设置断点,并逐步执行代码:
开发者工具
本指南提供了 WooCommerce 开发中必不可少的一些工具和库的概述。它面向希望高效地增强其 WooCommerce 项目的开发者。
生产力工具
使用这些资源来提升您的 WooCommerce 开发工作流程。
开发
wp-cli
这是 WordPress 的命令行界面。您可以在不使用 Web 浏览器的情况下,更新插件、配置多站点安装等等。
wc-cli
当 WooCommerce 运行在 WordPress 安装上时,WP-CLI 会扩展出额外的功能,用于管理您的商店数据。
wp-env
这个命令行工具让您能够轻松地设置一个本地的 WordPress Docker 环境,用于构建和测试插件和主题。它易于安装,无需任何配置。
woocommerce/eslint-plugin
这是一个 ESLint 插件,包含 WooCommerce 开发的配置和自定义规则。
WordPress Scripts
@wordpress/scripts 包是一组工具和脚本,旨在简化 WordPress 项目的开发过程,特别是用于块开发和自定义 Gutenberg 集成。它包括一个 Webpack 构建过程,以及用于执行诸如代码检查、样式和测试等任务的配置。
它还包括 Dependency Extraction Webpack Plugin,该插件允许 webpack 生成的 JavaScript 包利用 WordPress 样式依赖项共享,而无需手动维护依赖项列表,从而避免出现错误。
测试
Smooth Generator
一个插件,用于帮助您生成与 WooCommerce 相关的测试数据。使用 WP 管理界面执行基本操作,或使用命令行工具执行更高级的功能。从 发布页面 下载并安装最新版本,并查看 GitHub 上的文档。
WooCommerce Dummy Payments Gateway
一个用于 WooCommerce 开发的模拟支付网关,内置对订阅和基于块的结账的支持。
QIT
QIT 是一个用于测试 WooCommerce 插件和主题的测试平台,它提供托管的测试、端到端测试以及可丢弃的本地测试环境。
库
使用这些资源来简化数据获取和转换,以及创建 UI 元素。
API 客户端
WooCommerce REST API - JavaScript
用于与 WooCommerce REST API 交互的官方 JavaScript 库。
WooCommerce Store API
Store API 提供了面向客户的购物车、结账和产品功能的公共 REST API 接口。它遵循 WordPress REST API 中许多模式。
与 WooCommerce REST API 相比,Store API 不进行身份验证,并且不提供对敏感商店数据或其他客户信息的访问。
wordpress/api-fetch
@wordpress/api-fetch 包是一个实用工具,它简化了对 WordPress REST API 的 AJAX 请求。 这是一个 window.fetch 的包装器,它提供了一个一致的接口来处理身份验证、设置和错误,允许开发者轻松地与 WordPress 后端服务进行交互。
组件
WooCommerce Components
此包包含一个 React 组件库,可用于创建 WooCommerce 管理区域中的页面。 要预览这些组件,请查看 Woo Storybook。
WordPress Components
此包包含一个通用 WordPress 组件库,可用于创建 WordPress 仪表盘中屏幕和功能之间共享的常见 UI 元素。 要预览这些组件,请查看 Gutenberg Storybook。
JavaScript 实用工具包
CSV Export
一组函数,用于将数据转换为 CSV 值,并启用浏览器下载 CSV 数据。
Currency
一组实用程序,用于显示和处理货币值。
Data
用于管理 WooCommerce 管理数据存储的实用程序。
Date
一组实用程序,用于显示和处理日期值。
Navigation
一组与导航相关的函数,用于处理查询参数对象、序列化查询参数、更新查询参数以及触发路径更改。
Number
一组实用程序,用于正确地在 WooCommerce 中本地化数值。
设置您的开发环境
推荐软件
在开发 WooCommerce 扩展时,您需要考虑一些特定的软件要求。 必要的软件包括:
- Git 用于管理您的源代码的版本控制。
- Node.js 和 nvm 用于管理基于 Node.js 的脚本和构建过程。
- Pnpm 如果您是从代码仓库构建 WooCommerce,则需要此 npm 替代工具。
- Composer 是一个可选的依赖管理工具,用于 PHP 开发。
- WP-CLI 是 WordPress 的命令行界面。
大多数 WordPress 托管环境默认不包含 Node 和 Composer,因此在分发扩展和主题时,重要的是包含所有构建好的资源。
注意: 假设您使用的是符合 POSIX 标准的操作系统(例如,Linux、macOS)。 如果您正在使用 Windows 机器,建议使用 WSL(自 Windows 10 起可用)。
设置可重复使用的 WordPress 开发环境
除了上面提到的软件之外,您还需要一种方法来设置本地开发服务器环境。 有许多不同的工具可供选择,每个工具都有其特定的功能和限制。 我们建议您从以下选项中选择最适合您工作流程的选项。
WordPress Studio - 推荐方法
对于易于设置的本地开发环境,我们推荐 WordPress Studio,这是由 WordPress.com 团队支持的本地开发环境。 Studio 提供了管理多个本地网站环境的功能,以及与您的代码编辑器和终端的集成。 Studio 还具有 WordPress 专用的 AI 助手、从 WordPress 备份的轻松导入功能、Blueprint 支持、免费的公共预览站点以及与 WordPress.com 或 Pressable 上的站点进行双向同步。
wp-env
wp-env 是由 WordPress 社区维护的一个命令行工具,它允许您使用 Docker 和 JSON 配置文件来设置和运行自定义的 WordPress 环境。 仓库中包含一个 .wp-env.json 文件,专门用于为 WooCommerce 核心贡献代码。
通用基于 PHP 的 Web 栈工具
以下是一些帮助您管理环境的工具,这些工具不特定于 WordPress。
- MAMP - 可以在 Mac 或 Windows 上安装的本地服务器环境。
- WAMP - 允许您使用 Apache2、PHP 和 MySQL 创建应用程序的 Windows Web 开发环境。
- XAMPP - 一个易于安装的 Apache 发行版,包含 MariaDB、PHP 和 Perl。 适用于 Windows、Linux 和 OS X。
- Laravel Herd / Valet - 一个极简且快速的 macOS (Valet) 和 Windows (Herd) 开发环境,针对 Laravel 和其他 PHP 应用程序进行了优化。
- Lando - 一款功能强大的、基于 Docker 的工具,用于定义和管理各种语言和框架的本地开发服务。
- DDEV - 一款开源的、基于 Docker 的工具,用于简化本地 Web 开发,支持许多 CMS 和框架,例如 Drupal 和 WordPress。
- vvv 是一个高度可配置的、跨平台的、强大的环境管理工具,由 VirtualBox 和 Vagrant 提供支持。
最小服务器要求
无论您选择哪种工具来管理您的开发环境,您都应该确保它满足 WooCommerce 的 服务器推荐,以及 运行 WordPress 的要求。
将 WooCommerce 核心添加到您的环境
在为 WooCommerce 开发时,安装 WooCommerce 核心的开发版本会很有帮助。
选项 1:WooCommerce Beta Tester
如果您通过传统的 WordPress 仪表盘安装 WooCommerce,您还可以安装 WooCommerce Beta Tester 扩展,以更改版本,包括访问即将发布的 beta 版本和候选版本。 WooCommerce Beta tester 可通过 Woo Marketplace 获得。
选项 2:克隆 WooCommerce 核心仓库
您还可以通过以下方式,直接在您的开发环境中,针对 WooCommerce 核心的 trunk 或即将发布的版本进行开发:
- 克隆 WooCommerce 核心仓库。
- 安装并激活所需的 Node 版本和 PNPM。
- 安装 WooCommerce 的依赖项。
- 构建 WooCommerce。
- 将
plugin/woocommerce目录链接到您的wp-content/plugins目录。
克隆 WooCommerce 核心仓库
您可以使用以下 CLI 命令在本地克隆 WooCommerce 核心仓库:
cd /your/server/wp-content/plugins
git clone https://github.com/woocommerce/woocommerce.git
cd woocommerce
安装并激活 Node
建议使用 Node Version Manager (或 nvm) 来安装并激活 Node。 您可以使用以下 CLI 命令来安装 nvm:
nvm install
您可以在 nvm GitHub 仓库 中了解更多关于如何安装和使用 nvm 的信息。
安装依赖项
要安装 WooCommerce 的依赖项,请使用以下 CLI 命令:
pnpm install --frozen-lockfile
构建 WooCommerce
使用以下 CLI 命令来编译 WooCommerce 运行所需的 JavaScript 和 CSS 文件:
pnpm build
注意:如果您尝试在您的服务器上运行 WooCommerce,而没有生成编译后的资源,您可能会遇到错误和其他不良的效果。
创建 WooCommerce 插件的符号链接
为了将 WooCommerce 插件加载到您的本地开发环境,您可以从克隆的仓库中的 WooCommerce 插件目录创建一个符号链接,链接到您的本地 WordPress 开发环境。
ln -s woocommerce/plugins/woocommerce /path-to-local/wp-content/plugins
生成 woocommerce.zip 资源文件
或者,您可以使用以下命令生成一个 woocommerce.zip 文件:
pnpm build:zip
一个 woocommerce.zip 文件可能对您上传 WooCommerce 的修改版本到独立的测试环境时有所帮助。
项目结构
前置条件
WooCommerce 遵循 WordPress 的代码标准和指南,因此最好熟悉 WordPress 开发 以及 PHP。目前 WooCommerce 需要 PHP 7.4 或更高版本。
了解 WooCommerce 的钩子和过滤器 将允许您在不修改核心文件的情况下添加和更改代码。您可以在 WordPress 插件开发手册 中了解更多关于 WordPress 钩子和过滤器的信息。
推荐阅读
WooCommerce 扩展是一种特殊的 WordPress 插件。如果您是 WordPress 插件开发的初学者,请阅读 WordPress 插件开发者手册 中的一些文章。
WordPress 环境的结构
虽然开发环境可能有所不同,但 WordPress 环境的基本文件结构应该保持一致。
在开发 WooCommerce 扩展时,您通常会在本地服务器的 public_html/ 目录中进行大部分工作。
一个 WordPress 安装包含三个目录。wp-admin 和 wp-includes 目录包含核心功能,不应进行修改。第三个目录,wp-content,用于存储自定义配置和用户生成的媒体文件。
花一些时间熟悉 wp-content 目录下的几个关键路径:
wp-content/debug.log是 WordPress 写入重要输出的文件,例如错误和其他消息,这些消息对于调试很有用。wp-content/plugins/是服务器上存放 WordPress 插件文件夹的目录。wp-content/themes/是服务器上存放 WordPress 主题文件夹的目录。一个主题是一组模板和样式,并且 WordPress 只能有一个活动主题。
最后,在 WordPress 安装的根目录下还有一个可配置的文件,wp-config.php。该文件类似于 .env 文件,用于存储重要的安全凭据和变量,这些变量定义了您的环境配置。
WooCommerce 插件结构
当向 WordPress 安装添加 WooCommerce 时,您可以选择从 WordPress 仪表盘内部安装插件,或者手动将插件目录上传到 wp-content/plugins 目录。
重要: WooCommerce 仓库是一个单仓库,包含多个插件和包。要从仓库安装 WooCommerce,您不能简单地将整个仓库克隆到 wp-content/plugins 目录。WooCommerce 插件位于单仓库内的 plugins/ 目录中,因此,如果您计划从仓库进行开发,我们建议您将其克隆到本地 WordPress 安装之外,然后使用符号链接将其“放置”在 wp-content/plugins 目录中。
每个插件、包和工具都有自己的 package.json 文件,其中包含项目特定的依赖项和脚本。大多数项目还包含一个 README.md 文件,其中包含任何项目特定的设置说明和文档。
- Plugins: 我们的仓库包含与 WooCommerce 开发相关的插件和其他辅助工具。
- WooCommerce Core: 核心 WooCommerce 插件位于插件目录中,可用。
- Packages: 包目录包含所有提供的 PHP 和 JavaScript,供社区使用。其中一些是内部依赖项,并带有
internal-前缀。 - Tools: 我们的仓库中还拥有越来越多的工具。其中许多工具旨在用作单仓库中的实用程序和脚本,但此目录也可能包含外部工具。
如果您想了解更多关于我们单仓库的工作方式,请查看 此指南。
主题和扩展功能
除非您直接为 WooCommerce 核心代码做出贡献,否则您不会直接编辑 WordPress 或 WooCommerce 文件。所有功能的修改都通过创建自定义扩展或修改您当前主题的 functions.php 文件来完成。
要修改 WooCommerce 商店的 设计,我们建议修改或创建自定义主题。 了解更多关于如何在我们的 主题开发手册 中进行 WooCommerce 主题定制。
要修改 WooCommerce 商店的 功能,您有多种 选项。 首先,您可以使用 Woo Marketplace 查找合适的、现成的扩展程序,以满足您的需求。 对于简单的自定义,您可以了解更多关于轻松添加 代码片段 到您的商店的方法。 对于更高级的 开发 需求,我们建议构建自定义扩展程序(即,一个 WordPress 插件)。
模板和示例商店数据
WooCommerce 提供了多种入门套件和模板,具体取决于您正在构建的内容。
入门主题
如果您正在设计一个 WooCommerce 商店,您有两种主题开发选项:经典主题和区块主题。
- 经典主题使用 PHP 模板来覆盖商店中的关键页面设计,包括产品页面、产品归档、购物车和结账页面。虽然使用经典主题的网站可以使用 WordPress 区块编辑器,但许多模板无法在编辑器中直接编辑。
- 区块主题使用 WordPress 站点编辑器来生成 WordPress 站点的所有方面,包括页眉和页脚、产品页面、归档、购物车和结账页面。在站点编辑器中构建的设计可以导出为纯 HTML 文件,但这些文件通常在 WordPress 编辑器中进行编辑。
Storefront 主题 (经典)
Storefront 是 Woo 的旗舰经典主题,可在 WordPress 主题目录 中找到。您可以重命名并修改主题本身,也可以使用子主题来覆盖其特定方面。
有关构建经典 WooCommerce 主题的更多信息,请阅读我们的经典主题开发手册。有关创建子区块主题的综合指南以及了解经典主题和区块主题之间的差异,请参阅 WooCommerce 区块主题开发 和 WordPress 区块子主题开发。
区块入门主题
如果您是完全不了解区块主题开发,请查看 开发您的第一个低代码区块主题,以了解区块主题开发,并在准备创建新主题时,探索 Create Block Theme 插件 工具。
有关更多信息,请查看我们的 区块主题开发手册。
扩展模板
@woocommerce/create-woo-extension
Create Woo Extension 是一个 NPX 命令,用于为您的商店生成完整的 WooCommerce 扩展。生成的扩展程序包含一个基于 React 的设置页面,与 WooCommerce 后台集成。此外,还包括 PHP 和 JavaScript 单元测试、代码检查和 Prettier IDE 配置,适用于 WooCommerce 和 WordPress。
阅读我们关于使用 create-woo-extension 包 的完整教程。
@woocommerce/extend-cart-checkout-block
这是一个模板,用于与 @wordpress/create-block 配合,创建一个 WooCommerce Blocks 扩展的起点。要安装和使用它,请按照 @woocommerce/extend-cart-checkout-block 中的说明进行操作。请注意,这个示例包含多个其他扩展性的示例,而不仅仅是内部块。
WooCommerce 后台扩展示例
在 WooCommerce 插件中,有一组示例扩展,展示了修改 WooCommerce 核心功能的各种用例。一些示例包括添加自定义报告、自定义支付网关以及修改 WooCommerce 仪表盘。
阅读我们的完整教程,了解 如何扩展 WooCommerce 分析报告。
相关的 WordPress 框架
默认 WordPress 主题
默认的 WordPress 主题(截至本文编写时为 Twenty-Twenty Five)是一个了解 WordPress 块主题的最佳实践和标准规范的绝佳场所。使用 Create Block Theme 工具,您可以从网站编辑器中修改主题设计,然后将您的新设计导出到自定义子主题。
@wordpress/create-block
如果您正在向 WordPress 添加额外的内容或设计元素,那么创建一个自定义块可能是一个不错的选择。WordPress 块编辑器软件包库包含一个名为 WordPress Create Block 的脚手架工具,该工具可以帮助您创建可以插入到任何网页或模板中的自定义块。
了解更多关于 wordpress/create-block 软件包 的信息。
示例商店数据
核心插件示例数据
加载一些示例数据到您的本地商店可能很有帮助。在 WooCommerce 核心插件中,您可以找到 CSV 和 XML 文件,这些文件可以直接导入到 WooCommerce 中,可以使用 WordPress 后台或 WC-CLI。示例数据位于 /plugins/woocommerce/sample-data/。
Smooth Generator
对于更高级的测试,您可能需要一些示例客户和订单数据。Smooth Generator 是一款插件,可帮助您生成与 WooCommerce 相关的测试数据。使用 WP 后台界面进行基本操作,或使用 CLI 工具进行更高级的功能。从 发布页面 下载并安装最新版本,并浏览存储库以获取更多文档。
低代码开发工具
简介
本指南介绍了低代码解决方案,例如古腾堡 (Gutenberg) 和 WooCommerce 商店编辑功能,以及其他页面构建器和预构建组件,用于创建 WooCommerce 商店,而无需自定义代码。 通过理解和利用这些工具,低代码构建者可以仅用少量代码构建商店,并专注于其电子商务网站的设计和用户体验方面。
目标读者
本指南面向低代码构建者,或任何对 WordPress 和 WooCommerce 有基本了解,并且希望在无需大量自定义代码的情况下创建在线商店的人员。
前置条件
要遵循本指南,您应该具备:
- 对 WordPress 和 WooCommerce 的基本了解。
- 已经安装并启用了 WooCommerce 的 WordPress 网站。
第一步 - 使用古腾堡和 WooCommerce 商店编辑
古腾堡是 WordPress 默认的块编辑器,它允许您通过添加和自定义块来创建和编辑网页。 WooCommerce 扩展了古腾堡的功能,使您能够创建和自定义 WooCommerce 特定的元素,例如产品页面和商店页面。
要使用古腾堡和 WooCommerce 商店编辑:
- 确保您的 WordPress 安装是最新版本,以获得古腾堡的最新版本。
- 安装并激活一个块主题,以启用 WooCommerce 的商店编辑功能。
使用古腾堡和 WooCommerce 商店编辑,您可以使用各种各样的块来创建和自定义商店的页面,例如文本、图像、按钮以及 WooCommerce 特定的块,如产品网格和购物车。
第二步 - 探索其他页面构建器
虽然古腾堡和 WooCommerce 商店编辑是构建低代码 WooCommerce 商店的强大选项,但您可能还想考虑使用其他页面构建器,以获得更高级的功能或特定用例。 一些与 WooCommerce 兼容的流行页面构建器包括:
- Elementor
- Beaver Builder
- Divi Builder
- WPBakery Page Builder
选择适合您的需求和预算的页面构建器,然后在您的 WordPress 网站上安装并激活它。 这些页面构建器通常提供一个预构建组件库,您可以使用这些组件来创建完全功能的 WooCommerce 商店,而无需编写自定义代码。
第 3 步 - 使用预制组件和模板
许多网页构建器,包括古腾堡,都提供预制组件或模块,可以轻松地添加到您的网页中。 这些组件可以包含设计元素,例如按钮、表单和图像库,以及 WooCommerce 专用的组件,例如产品网格和购物车。
此外,一些网页构建器和 WooCommerce 扩展程序提供预制商店模板,您可以导入并自定义这些模板,以快速创建功能齐全的在线商店。 这些模板可以为您节省时间和精力,因为它们提供了一个经过专业设计的起点。
要使用预制组件和模板:
- 打开您喜欢的网页构建器的编辑器(古腾堡或其他网页构建器)。
- 浏览可用的组件/模块或模板,找到适合您需求的内容。
- 将组件添加到您的网页中,并使用提供的设置和选项进行自定义。
结论
通过利用低代码解决方案,例如古腾堡、WooCommerce 商店编辑和其他网页构建器,您可以在无需自定义编码的情况下创建功能齐全的 WooCommerce 商店。 本指南向您介绍了这些工具的基本用法,帮助您了解可用的选项,并使用最少的编码来组装您的商店。 通过正确的工具和模板组合,您可以创建一个专业、用户友好的电子商务网站,以满足您的业务需求。
版本控制和部署
由于 WordPress 和 WooCommerce 既是开发者框架,又是内容管理系统,因此在规划如何进行代码版本控制以及如何将更改部署到生产环境时,至关重要。一个常见的规则是“代码向上,内容向下”,这意味着您会将自定义代码从本地或测试环境推送到生产环境,但永远不要推送数据库的内容或存储在 wp-content/uploads 目录中的用户生成内容。
考虑事项
WordPress 的部署没有一种适用于所有情况的方法。您的托管环境可能具有专门的方法,您需要遵循这些方法,尤其是在像 WordPress VIP 这样的企业级托管平台上。
根据 WordPress 安装的 项目结构 以及您的独特需求,您可能会对 wp-content 目录的不同部分进行版本控制和部署。一些常见的做法包括:
- 从 WordPress 的根目录开始进行版本控制,但包含一个
.gitignore文件,该文件忽略大部分 WordPress 核心和插件,如果您的托管公司负责 WordPress 更新。一个示例.gitignore文件可从 GitHub 获得,您可以更新它以确保您的自定义代码被版本控制。这种方法在管理每个站点的独立仓库的开发者中更受欢迎。 - 仅对您正在使用的目录进行版本控制,通常位于
wp-content/plugins/your-extension或wp-content/themes/your-theme。这种方法对于广泛在多个站点上分发其代码的扩展和主题开发者来说更为常见。
注意: 请勿将 wp-config.php 文件提交到公共仓库。它可能包含敏感信息,并且很可能与您的本地和生产环境不同。
构建和部署
大多数 WordPress 托管环境 不支持 Node 或 Composer。您需要确认您正在部署的环境,并在设置工作流程时牢记这一点。一些流行的做法包括:
- 将构建好的文件提交到您的仓库。例如,来自 WordPress.org 目录的插件和主题包含所有构建好的资源,以便于更新。
- 通过工具(如 GitHub Actions)或独立的 CI/CD 管道添加构建步骤。
购物车和结账模块的主题定制
[!IMPORTANT] 我们强烈建议不要基于现有的模块类名编写 CSS 代码,并且尽可能使用全局样式。 我们尤其不建议编写依赖于特定模块是另一个模块的子元素的 CSS 选择器,因为用户可以自由移动模块,因此很容易导致代码失效。 类似于 WordPress 本身,我们认为组件、模块和模块模板中的 HTML 结构是“私有”的,并且可能会在未来进一步更改,因此使用 CSS 针对模块或模块模板的内部结构_不建议也不支持_。
按钮
WC Blocks 引入了按钮组件,它与普通的 button 元素不同,因为它具有一些默认样式,使其能够很好地融入 Blocks 的设计。

主题仍然可以对它们进行样式设置,以匹配主题颜色或样式,如下所示:
.wc-block-components-button {
background-color: #d5502f;
color: #fff;
/* 可以添加更多规则来修改边框、阴影等 */
}
/* 可能需要修改悬停、聚焦、激活和禁用状态 */

移动设备上的提交容器
在小屏幕视口中,购物车模块在屏幕底部的固定容器内显示 继续结账 按钮。

默认情况下,该容器具有白色背景,因此与按钮组件的默认颜色相得益彰。 如果主题希望应用与页面其他部分相同的背景颜色,可以使用以下代码片段:
.wc-block-cart__submit-container {
background-color: #f9f4ee;
}
请注意,该容器具有顶部的盒子阴影,这可能与某些深色背景颜色不协调。 如果需要,可以直接修改 color 属性(内部,阴影颜色使用 currentColor,因此它会尊重 color 属性):
.wc-block-cart__submit-container::before {
color: rgba( 214, 209, 203, 0.5 );
}
或者,主题可以完全覆盖 box-shadow 属性:
.wc-block-cart__submit-container::before {
box-shadow: 0 -10px 20px 10px rgba( 214, 209, 203, 0.5 );
}

商品数量标识
商品数量标识是位于 结账 块侧边栏的 订单摘要 部分中,显示在图像旁边的数值。

默认情况下,它使用黑色和白色边框和阴影,以确保其与浅色和深色背景的主题具有足够的对比度。 主题可以使用单个 CSS 选择器和四个属性来修改颜色,从而使用自己的调色板。 例如:
.wc-block-components-order-summary-item__quantity {
background-color: #f9f4ee;
border-color: #4b3918;
box-shadow: 0 0 0 2px #f9f4ee;
color: #4b3918;
}

CSS 样式设置用于主题
块和组件的类名
[!IMPORTANT] 我们强烈建议不要基于现有的块类名编写 CSS 代码,并且尽可能使用全局样式。 我们特别不建议编写依赖于某个块是另一个块的子元素的 CSS 选择器,因为用户可以自由地移动块,这很容易导致代码中断。 类似于 WordPress 本身,我们认为组件、块和块模板中的 HTML 结构是“私有”的,并且可能会在未来进一步更改,因此使用 CSS 针对块或块模板的内部结构_不建议也不支持_。
WooCommerce Blocks 遵循 BEM 的类名规范,如 我们的编码指南 中所述。 所有类名都以以下两个前缀之一开头:
.wc-block-: 特定于单个块的类名。.wc-block-components-: 特定于组件的类名。 该组件可能被不同的块重复使用。
块类名和组件类名的组合允许主题全局或仅在特定块中对每个组件进行样式设置。 例如,您可以将所有价格设置为斜体:
/* 这将应用于所有块中的价格 */
.wc-block-components-formatted-money-amount {
font-style: italic;
}
但是,如果您只想在结账块中将其设置为斜体,则可以添加块选择器:
/* 这将应用于结账块中的价格 */
.wc-block-checkout .wc-block-components-formatted-money-amount {
font-style: italic;
}
注意: 为了向后兼容,某些组件可能具有同时具有两个前缀的类名(例如:wc-block-sort-select 和 wc-block-components-sort-select)。 在这些情况下,以 .wc-block- 开头的类名已过时,不应在新代码中使用。 它将在未来的版本中被移除。 如果一个元素具有两个类,请始终使用以 .wc-block-components- 开头的类。
容器查询类名
某些组件具有根据容器宽度而变化的响应式类。 使用这些类而不是 CSS 媒体查询的原因是为了适应添加块的容器(CSS 媒体查询仅允许响应视口大小)。
这些类是:
| 容器宽度 | 类名 |
|---|---|
| >700px | is-large |
| 521px-700px | is-medium |
| 401px-520px | is-small |
| <=400px | is-mobile |
例如,如果我们要使结账字号在容器宽度为 521px 或更大的情况下增加 10%,可以使用以下代码:
.wc-block-checkout.is-medium,
.wc-block-checkout.is-large {
font-size: 1.1em;
}
CSS 容器查询在购物车和结账模块中的应用
WooCommerce 将购物车和结账模块的顶层包装器定义为 CSS 容器。这些容器使用 container-type: inline-size:
.wp-block-woocommerce-checkout {
container-type: inline-size;
}
开发者可以使用 CSS 容器查询 (@container) 来根据父容器的宽度来设置子 组件 的样式,从而避免使用像 .is-large 这样的通过 JavaScript 添加的类,这些类被认为是过时的。虽然为了向后 兼容性,旧的类仍然存在,但我们建议使用容器方法来实现更简洁的样式和更少的布局变化。
注意: 只要在结账模块的包装器和要设置样式的 元素 之间没有其他容器,容器查询就能正常工作。如果在您的 主题 或插件中定义了额外的 CSS 容器,它们可能会干扰容器查询的行为。
提供了 SCSS 混合宏,作为方便的辅助工具,用于针对之前由类如 .is-large、.is-medium、.is-small 和 .is-mobile 定义的相同宽度 断点。这些混合宏可以更轻松地根据容器宽度来设置购物车和结账模块内部内容的样式。
// 之前,使用 JavaScript 生成的 CSS 类
.is-large {
.your-class {
padding: 2rem;
}
}
// 之后,使用容器混合宏
@include cart-checkout-large-container {
.your-class {
padding: 2rem;
}
}
// 之后,使用纯 CSS
@container (min-width: 700px) {
.your-class {
padding: 2rem;
}
}
WC Blocks 与主题样式冲突在语义元素中的问题
WooCommerce Blocks 使用 HTML 元素,其依据是它们的语义含义,而不是它们的默认布局。这意味着,有时块可能会使用锚链接 (<a>),但将其显示为按钮。或者反过来,<button> 可能会显示为文本链接。类似地,标题可能会显示为普通文本。
在这种情况下,Blocks 包含一些 CSS 重置,以撤销 主题 引入的大部分默认样式。如果一个 <button> 显示为文本链接,它很可能具有背景、边框等的重置。这通常可以解决大部分问题,但在某些情况下,如果 主题 具有具有更高特异性的特定 CSS 选择器,这些 CSS 重置可能无法生效。在这种情况下,我们强烈建议 主题 开发者降低其选择器的特异性,以便 Blocks 的样式具有更高的优先级。如果无法做到这一点,主题 可以在其之上编写 CSS 重置。
隐藏的元素
WooCommerce 的旧类(.price, .star-rating, .button...)
WooCommerce 区块在很大程度上避免使用没有前缀的旧类。 但是,您可能会发现一些为了向后兼容而添加的旧类。 我们仍然建议主题尽可能使用带有前缀的类,这可以避免与其他插件、编辑器等的冲突。
Customizing the WooCommerce Blocks theme
You can customize the WooCommerce Blocks theme by adding custom CSS. You can also use the wc_enqueue_scripts action to add custom JavaScript.
Here are some examples:
- To change the color of the "Add to cart" button, you can use the following CSS:
.wc-block-button {
background-color: %s;
}
- To add a custom JavaScript file, you can use the following code:
wp.customize.control(
'wc_blocks_custom_js',
{
type: 'file',
label: 'Select JavaScript file',
priority: 10,
attribute: 'src',
value: '',
}
)
Compatibility
WooCommerce Blocks is compatible with all major browsers and versions of WooCommerce. However, some features may not be available in all browsers.
For more information on compatibility, please see the WooCommerce Blocks documentation.
Other plugins
WooCommerce Blocks is compatible with most other plugins. However, some plugins may not be compatible with WooCommerce Blocks.
If you are having trouble with a plugin, please contact the plugin developer for support.
Troubleshooting
If you are having trouble with WooCommerce Blocks, please see the WooCommerce Blocks troubleshooting guide.
Support
If you have any questions or need help with WooCommerce Blocks, please contact us at support@woocommerce.com.
Contributing
We welcome contributions from the community. If you would like to contribute to WooCommerce Blocks, please see the WooCommerce Blocks contribution guidelines.
License
WooCommerce Blocks is licensed under the GPL-2.0+ license.
Table of Contents
WooCommerce Blocks
WooCommerce Blocks is a collection of blocks for the Gutenberg editor. These blocks allow you to easily add WooCommerce functionality to your website.
The WooCommerce Blocks are designed to be easy to use and customize. You can use them to create a variety of different types of pages, including product pages, category pages, and cart pages.
The WooCommerce Blocks are also designed to be compatible with a wide range of themes and plugins.
Adding a WooCommerce Blocks theme
To add a WooCommerce Blocks theme, you will need to install the WooCommerce plugin and the WooCommerce Blocks plugin.
Once you have installed the plugins, you can activate the WooCommerce Blocks theme by going to the "Appearance" > "Themes" page in the WordPress admin panel.
Using the WooCommerce Blocks editor
The WooCommerce Blocks editor is a powerful tool for creating WooCommerce pages. It allows you to easily add and edit WooCommerce content.
The WooCommerce Blocks editor is also designed to be compatible with a wide range of themes and plugins.
Editing a WooCommerce Blocks page
To edit a WooCommerce Blocks page, you will need to open the page in the WordPress editor.
Once you have opened the page, you can click on the "Edit" button to open the WooCommerce Blocks editor.
Finding a WooCommerce Blocks page
To find a WooCommerce Blocks page, you can use the search function in the WordPress admin panel.
You can also use the "Pages" > "All Pages" page to view a list of all of your pages.
Locking a WooCommerce Blocks page
You can lock a WooCommerce Blocks page to prevent it from being edited.
To lock a page, you will need to open the page in the WordPress editor and click on the "Lock" button.
Using the WooCommerce Blocks API
The WooCommerce Blocks API allows you to programmatically access and modify WooCommerce content.
You can use the API to create new WooCommerce pages, edit existing pages, and retrieve data from WooCommerce.
For more information
For more information on WooCommerce Blocks, please see the WooCommerce Blocks documentation.
Rating
Please rate this document.
Back
返回
From
从
In
在
Use
使用
Woo blocks 主题定制
注意: 我们假设您已经具备一些关于区块主题开发的知识以及一些 WordPress 的概念。 如果您是完全不了解区块主题开发的新手,请查看 Develop Your First Low-Code Block Theme 以了解区块主题开发,并在准备创建新主题时,探索 Create Block Theme plugin 工具。
常用概念
区块模板
WooCommerce 默认提供以下几个 区块模板:
- 单个产品 (
single-product.html) - 产品目录 (
archive-product.html)- 按分类的产品 (
taxonomy-product_cat.html) - 按标签的产品 (
taxonomy-product_tag.html) - 按属性的产品 (
taxonomy-product_attribute.html)
- 按分类的产品 (
- 产品搜索结果 (
product-search-results.html) - 网页: 即将推出 (
page-coming-soon.html) - 网页: 购物车 (
page-cart.html) - 网页: 结账 (
page-checkout.html) - 订单确认 (
order-confirmation.html)
区块主题可以通过以下方式自定义这些模板:
- 可以通过在
/templates文件夹下创建一个同名文件来覆盖模板。 例如,如果区块主题包含wp-content/themes/yourtheme/templates/single-product.html模板,它将优先于 WooCommerce 默认的单个产品模板。 - 按分类、按标签和按属性的产品模板会回退到产品目录模板。 换句话说,如果主题提供
archive-product.html模板,但没有提供taxonomy-product_cat.html模板,则按分类的产品模板将使用archive-product.html模板。 同样适用于按标签和按属性的产品模板。 - 也可以为特定产品和分类法创建模板。 例如,如果主题提供一个文件名
single-product-cap.html的模板,则该模板将用于渲染别名为cap的产品。 类似地,主题可以提供特定的分类法模板:taxonomy-product_cat-clothing.html将用于别名为clothing的产品分类。 - 请始终记住,用户可以通过站点编辑器修改主题提供的模板。
区块模板部件
WooCommerce 还提供两个特定的 区块模板部件:
- 迷你购物车 (
mini-cart.html):用于迷你购物车区块抽屉。 - 结账头部 (
checkout-header.html):用作结账模板的头部。
与模板类似,主题可以通过在 /parts 文件夹下添加一个同名文件来覆盖这些部件。
全局样式
WooCommerce 块依赖于 全局样式 来进行样式设置。全局样式可以通过主题的 theme.json 文件或用户通过“外观 > 编辑器 > 样式”来定义,相比于纯 CSS,它具有以下优势:
- 更好的性能,因为只有所需的 CSS 才会输出到页面,从而减少渲染页面的文件大小。
- 用户可以通过界面轻松自定义。
- 优雅地处理插件和主题之间的冲突。
- 不受单个块或组件中的标记或类名更新的影响。
- 不依赖于块的特定嵌套顺序:用户可以自由地移动块,而不会导致样式中断。
示例
例如,假设您正在构建一个主题,并且希望自定义“产品价格”块的样式,您可以这样做,通过在您的 theme.json 文件中添加以下属性:
"styles": {
"blocks": {
"woocommerce/product-price": {
"color": {
"background": "#00cc00",
"text": "#fff"
},
"typography": {
"fontStyle": "italic",
"fontWeight": "700"
}
}
...
}
...
}
| 之前 | 之后 |
|---|---|
您可以在 developer.wordpress.org 上找到更多关于 全局样式 的 文档。您还可以找到 WooCommerce 块及其名称的列表。
主题的 CSS 样式
区块和组件类名
[!IMPORTANT] 我们强烈建议不要基于现有的区块类名编写 CSS 代码,并优先使用全局样式。我们尤其不建议编写依赖于特定区块作为另一个区块后代的 CSS 选择器,因为用户可以自由移动区块,所以这些选择器很容易失效。与 WordPress 本身类似,我们认为组件、区块和区块模板内的 HTML 结构是“私密”的,未来可能会进一步更改,因此不建议或不支持使用 CSS 来定位区块或区块模板的内部结构。
WooCommerce Blocks 遵循 BEM 命名规范,如我们的编码指南中所述。所有类名都以以下两个前缀之一开头:
.wc-block-:特定于单个区块的类名。.wc-block-components-:特定于组件的类名。该组件可能被不同的区块重复使用。
区块类名和组件类名的组合允许主题全局地或仅在特定区块中对每个组件进行样式设置。例如,您可以使用以下代码将所有价格设置为斜体:
/* 这将应用于所有区块价格 */
.wc-block-components-formatted-money-amount {
font-style: italic;
}
但如果你只想在结账区块中将其设为斜体,可以通过添加区块选择器来实现:
/* 这将应用于结账区块中的价格 */
.wc-block-checkout .wc-block-components-formatted-money-amount {
font-style: italic;
}
注意: 为了向后兼容,某些组件可能同时具有两种前缀的类名(例如:wc-block-sort-select 和 wc-block-components-sort-select)。在这些情况下,带有 .wc-block- 前缀的类名已被弃用,不应在新代码中使用。它将在未来版本中被移除。如果一个元素同时具有两个类,请始终使用带有 .wc-block-components- 前缀的类进行样式设置。
容器查询类名
我们的一些组件具有根据容器宽度变化的响应式类。使用这些类而非 CSS 媒体查询的原因是为了适应区块被添加到的容器(CSS 媒体查询仅允许响应视口尺寸)。
这些类如下:
| 容器宽度 | 类名 |
|---|---|
| >700px | is-large |
| 521px-700px | is-medium |
| 401px-520px | is-small |
| <=400px | is-mobile |
例如,如果我们希望在容器宽度为 521px 或更宽时,将结账字体大小增加 10%,可以使用以下代码实现:
.wc-block-checkout.is-medium,
.wc-block-checkout.is-large {
font-size: 1.1em;
}
购物车和结账区块的 CSS 容器查询
WooCommerce 将购物车和结账区块的顶层包装器定义为 CSS 容器。这些容器使用 container-type: inline-size:
.wp-block-woocommerce-checkout {
container-type: inline-size;
}
开发者可以使用 CSS 容器查询 (@container) 根据父容器宽度来设置子组件的样式,从而无需使用由 JS 添加的类(例如被视为遗留的 .is-large)。为了向后兼容,遗留类仍然保留,但我们建议使用容器方法,以实现更简洁的样式和更少的布局偏移。
注意: 只要在结账区块包装器和要设置样式的元素之间没有其他容器,容器查询就能正常工作。如果您在主题或插件中定义了额外的 CSS 容器,它们可能会干扰容器查询的行为。
我们提供了 SCSS 混合宏作为便捷的辅助工具,用于定位之前由 .is-large、.is-medium、.is-small 和 .is-mobile 等类定义的相同宽度断点。这些混合宏使得根据容器宽度来设置购物车和结账区块内部内容的样式变得更加容易。
// 之前,使用 JS 生成的 CSS 类
.is-large {
.your-class {
padding: 2rem;
}
}
// 之后,使用容器混合宏
@include cart-checkout-large-container {
.your-class {
padding: 2rem;
}
}
// 后,使用纯 CSS @container (min-width: 700px) { .your-class { padding: 2rem; } }
## WC 区块与主题样式在语义元素上的冲突
WooCommerce Blocks 根据语义含义而非默认布局来使用 HTML 元素。这意味着有时区块可能使用锚链接(`<a>`),但将其显示为按钮。或者反过来,一个 `<button>` 可能被显示为文本链接。同样,标题也可能被显示为常规文本。
在这些情况下,区块包含一些 CSS 重置,以撤销主题引入的大多数默认样式。一个显示为文本链接的 `<button>` 可能会重置背景、边框等样式。这将解决大多数开箱即用的冲突,但在某些情况下,如果主题具有更高特异性的特定 CSS 选择器,这些 CSS 重置可能不会生效。当这种情况发生时,我们强烈鼓励主题开发者降低其选择器的特异性,以便区块样式获得优先权;如果无法做到这一点,主题可以在顶部编写 CSS 重置。
## 隐藏元素
WC 区块使用 [`hidden` HTML 属性](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden) 来隐藏用户界面中的某些元素,使其既不在屏幕上显示,也不被辅助技术阅读。如果您的主题有一些通用的样式来调整区块元素的 CSS 显示属性(例如:`div { display: block; }`),请确保正确处理 hidden 属性:`div[hidden] { display: none; }`。
## WooCommerce 遗留类(.price、.star-rating、.button...)
WooCommerce Blocks 尽可能避免使用未加前缀的遗留类。但您可能会发现,为了向后兼容性,其中一些类已被添加。我们仍然鼓励主题在可能的情况下使用带前缀的类,这可以避免与其他插件、编辑器等发生冲突。
经典主题开发手册
注意: 本文档面向经典主题的开发。请查看此其他文档,了解块主题的开发。
从版本 3.3 开始,WooCommerce 与所有 WordPress 主题兼容,即使这些主题不是专门为 WooCommerce 设计的,并且没有正式声明支持。模板会嵌入到内容中,这使得您的网站看起来更加自然。
默认情况下,非 WooCommerce 主题也包含以下功能:
- 启用缩放功能:允许用户放大/缩小产品图片。
- 启用灯箱功能:产品画廊图片会弹出,以便用户更仔细地查看。
- 启用评论功能,而不是评价:访客/买家可以留下评论,而不是产品评分或评价。
如果您希望对 WooCommerce 元素的布局进行更多控制,或者需要完整的评价支持,您的主题需要与 WooCommerce 集成。有几种不同的方法可以实现这一点,下面将详细介绍。
主题集成
有三种可能的将 WooCommerce 与主题集成的方案。如果您使用的是 WooCommerce 3.2 或更早版本(强烈不建议),则需要使用以下一种方法,以确保 WooCommerce 商店和产品页面在您的主题中正确显示。如果您使用的是 WooCommerce 3.3 或更高版本,则只有在自动集成无法满足您的需求时,才需要进行主题集成。
使用 woocommerce_content()
此解决方案允许您在主题中创建一个新的模板页面,该页面用于所有 WooCommerce 分类和帖子类型显示。虽然这是一种简单的通用解决方案,但它有一个缺点,即此模板用于所有 WooCommerce 分类(产品分类等)和帖子类型(产品归档、单个产品页面)。建议开发者使用以下钩子(hooks)来实现更精细的控制。
要设置此模板页面:
- 复制
page.php: 复制您主题的page.php文件,并将其重命名为woocommerce.php。该文件的路径应遵循以下模式:wp-content/themes/YOURTHEME/woocommerce.php。 - 编辑您的页面 (woocommerce.php):使用文本编辑器打开您新创建的
woocommerce.php文件。 - 替换循环 (loop):接下来,您需要找到循环(loop)(请参阅 The_Loop)。循环通常以类似这样的代码开始:
<?php if ( have_posts() ) :
它通常以类似这样的代码结束:
<?php endif; ?>
不同主题的循环结构可能有所不同。找到循环后,将其删除。然后,在此处插入以下代码:
<?php woocommerce_content(); ?>
这将使用WooCommerce 的循环。保存文件。完成。
注意: 当您在主题文件夹中创建 woocommerce.php 时,您将无法覆盖 woocommerce/archive-product.php 自定义模板,因为 woocommerce.php 的优先级高于 archive-product.php。这是为了防止显示问题。
使用钩子
钩子方法涉及的步骤更多,但它也更灵活。这类似于我们在创建主题时使用的方法。这也是我们与 WordPress 默认主题集成的方法。
在您主题的 functions.php 文件中插入几行代码。
首先,取消 WooCommerce 的包装函数:
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);
然后,添加您自己的函数来显示您的主题所需的包装:
add_action('woocommerce_before_main_content', 'my_theme_wrapper_start', 10);
add_action('woocommerce_after_main_content', 'my_theme_wrapper_end', 10);
function my_theme_wrapper_start() {
echo '<section id="main">';
}
function my_theme_wrapper_end() {
echo '</section>';
}
请确保标记与您的主题相匹配。如果您不确定应该使用哪些类或 ID,请查看您主题的 page.php 文件以获取指导。
尽可能使用钩子来添加或移除内容。 这种方法比覆盖模板更健壮。 如果您覆盖了一个模板,则每次文件更改时都必须更新该模板。 如果您使用的是钩子,则只有在钩子发生更改时才需要更新,而这种情况发生的频率要低得多。
使用模板覆盖
有关如何使用您自己的自定义模板覆盖 WooCommerce 模板的信息,请参阅下面的模板结构部分。 这种方法需要比基于钩子的方法更多的维护,因为模板需要保持与 WooCommerce 核心模板的同步。
声明 WooCommerce 支持
如果您在主题中使用自定义的 WooCommerce 模板覆盖,则需要使用 add_theme_support 函数来声明 WooCommerce 支持。 只有声明了 WooCommerce 支持的主题才能启用 WooCommerce 模板覆盖。 如果您在主题中未声明 WooCommerce 支持,WooCommerce 会假定该主题未针对 WooCommerce 兼容性进行设计,并将使用基于短代码的、不受支持的主题渲染方式来显示商店。
声明 WooCommerce 支持非常简单,只需在您主题的 functions.php 文件中添加一个函数。
基本用法
function mytheme_add_woocommerce_support() {
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'mytheme_add_woocommerce_support' );
请确保您使用的是 after_setup_theme 钩子,而不是 init 钩子。 更多关于此的信息,请参阅 关于 add_theme_support 的文档。
使用 Settings
function mytheme_add_woocommerce_support() {
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 150,
'single_image_width' => 300,
'product_grid' => array(
'default_rows' => 3,
'min_rows' => 2,
'max_rows' => 8,
'default_columns' => 4,
'min_columns' => 2,
'max_columns' => 5,
),
) );
}
add_action( 'after_setup_theme', 'mytheme_add_woocommerce_support' );
这些是可选的 主题 设置,您可以在声明 WooCommerce 支持时进行设置。
thumbnail_image_width 和 single_image_width 将设置商店的 图片尺寸。 如果在添加 主题 支持时未声明这些设置,用户可以在自定义工具栏的 WooCommerce > 产品图像 部分 中设置 图片尺寸。
product_grid 设置允许 开发者 设置商店的默认、最小和最大 列 和行设置。 用户可以在自定义工具栏的 WooCommerce > 产品目录 部分 中设置行和 列。
产品画廊功能(缩放、滑动、灯箱)
3.0.0 版本引入的产品画廊 (更多信息请阅读此处) 使用 Flexslider、Photoswipe 和 jQuery Zoom 插件,提供滑动、灯箱 和其他实用功能。
在 版本 3.0、3.1 和 3.2 中,新的画廊默认情况下是禁用的,需要使用代码片段(如下所示)或使用兼容的 主题 启用。 这是因为 主题 经常会禁用 WooCommerce 画廊,并用自己的 脚本 替换它。
在 版本 3.3+ 中,对于 WooCommerce 兼容的 主题 来说,画廊默认情况下是禁用的,除非它们声明支持它(如下所示)。 没有 WooCommerce 支持的第三方 主题 默认情况下会启用画廊。
要启用您 主题 中的画廊,您可以像这样声明支持:
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
您不必支持画廊的所有三个 部分;您可以选择您需要的特性。 如果某个特性未启用,则不会加载相应的 脚本,并且画廊代码将不会在产品页面上执行。
如果启用了画廊功能(例如,您有一个启用了它们的 主题,或者您正在使用一个与 WooCommerce 不兼容的 主题),您可以使用 remove_theme_support 禁用它们:
remove_theme_support( 'wc-product-gallery-zoom' );
remove_theme_support( 'wc-product-gallery-lightbox' );
remove_theme_support( 'wc-product-gallery-slider' );
您可以禁用任何 部分;您不必禁用所有功能。
模板结构
WooCommerce 模板文件包含 标记 和 模板结构,用于您商店的 前端 以及 HTML 邮件。 如果需要在 HTML 中进行某些结构性更改,您应该覆盖一个模板。
打开这些文件时,您会发现它们都包含 钩子,允许您添加或移动内容,而无需直接编辑模板文件本身。 这种方法可以防止升级问题,因为模板文件可以完全保持不变。
模板文件位于 **/woocommerce/templates/** 目录中。
如何编辑文件
使用 覆盖 以一种 安全升级 的方式编辑文件。 将它们复制到您主题中的一个名为 /woocommerce 的目录中,保持相同的目录结构,但删除 /templates/ 子目录。
例如:要覆盖管理订单通知,请将 wp-content/plugins/woocommerce/templates/emails/admin-new-order.php 复制到 wp-content/themes/yourtheme/woocommerce/emails/admin-new-order.php。
复制的文件现在将覆盖 WooCommerce 的默认模板文件。
警告: 在覆盖模板时,请勿删除任何 WooCommerce 钩子。 否则,插件将无法挂载以添加内容。
警告: 请勿在核心插件本身中编辑这些文件,因为在升级过程中,它们会被覆盖,并且所有自定义内容都将丢失。
CSS 结构
在 assets/css/ 目录中,您将找到负责默认 WooCommerce 布局样式的样式表。
需要关注的文件是 woocommerce.scss 和 woocommerce.css。
woocommerce.css是压缩的样式表,它不包含任何空格、缩进等。 这使得该文件加载速度非常快。 插件会引用此文件,并声明所有 WooCommerce 样式。woocommerce.scss不直接由插件使用,而是由开发 WooCommerce 的团队使用的。 我们使用 SASS 在此文件中生成第一个文件中的 CSS。
CSS 的编写方式是使其与尽可能多的主题兼容,通过为所有布局样式使用基于百分比的宽度。 但是,您可能希望进行自己的调整。
修改
为了避免升级问题,我们建议不要编辑这些文件,而是将它们用作参考。
如果您只想进行更改,我们建议将一些覆盖样式添加到您的主题样式表中。 例如,将以下代码添加到您的主题样式表中,以将 WooCommerce 按钮的颜色更改为黑色,而不是默认颜色:
a.button,
button.button,
input.button,
#review_form #submit {
background:black;
}
WooCommerce 还将主题名称(以及其他有用的信息,例如正在查看的页面类型)作为类添加到 body 标签中,这对于覆盖样式非常有用。
禁用 WooCommerce 样式
如果您计划进行重大更改,或者从头开始创建一个主题,那么您可能更喜欢您的主题完全不引用 WooCommerce 的样式表。 您可以通过将以下代码添加到您主题的 functions.php 文件中,来告诉 WooCommerce 不要使用默认的 woocommerce.css 文件:
add_filter( 'woocommerce_enqueue_styles', '__return_false' );
通过这个定义,您的主题将不再使用 WooCommerce 的样式表,而是为您提供一个空白的画布,您可以在此基础上构建您自己的布局和样式。
第一次从头开始为 WooCommerce 主题进行样式设置是一项艰巨的任务。 有许多不同的网页和元素需要进行样式设置,如果您是 WooCommerce 的新手,您可能不熟悉其中的许多元素。 可以在此 WooCommerce 主题测试清单 中找到 WooCommerce 元素的非完整列表。
WooCommerce 中的条件标签
什么是“条件标签”?
WooCommerce 和 WordPress 的条件标签可以在您的模板文件中使用,以根据网页满足的条件来改变显示的内容。 例如,您可能希望在商店页面上方显示一段文本。 使用 is_shop() 条件标签,您可以实现这一点。
由于 WooCommerce 使用自定义文章类型,因此您也可以使用许多 WordPress 的条件标签。 请参阅 codex.wordpress.org/Conditional_Tags,了解 WordPress 包含的标签列表。
注意: 您只能在 WordPress 中 posts_selection 动作钩子 之后使用条件查询标签(wp 动作钩子是第一个可以用于这些条件的钩子)。 对于主题,这意味着如果将条件标签放在 functions.php 文件的 body 部分,则它永远无法正常工作。
可用的条件标签
所有条件标签都测试某个条件是否满足,然后返回 TRUE 或 FALSE。 在每个条件标签下方列出了使该标签输出 TRUE 的条件。
以下列表包含主要的条件标签。 要查看所有条件标签,请访问 WooCommerce API 文档。
WooCommerce 页面
is_woocommerce()如果当前页面使用 WooCommerce 模板(购物车和结账页面是标准页面,包含短代码,因此不在此范围内),则返回 true。
主商店页面
is_shop()当访问产品归档页面(商店)时,返回 true。
产品分类页面
is_product_category()当浏览产品分类归档时,返回 true。is_product_category( 'shirts' )当正在显示“shirts”分类的产品分类页面时。is_product_category( array( 'shirts', 'games' ) )当正在显示“shirts”或“games”分类的产品分类页面时。
产品标签页面
is_product_tag()当浏览产品标签归档时,返回 true。is_product_tag( 'shirts' )当正在显示“shirts”标签的产品标签页面时。is_product_tag( array( 'shirts', 'games' ) )当正在显示“shirts”或“games”标签的产品标签页面时。
单个产品页面
is_product()当访问单个产品页面时,返回 true。 相当于is_singular。
购物车页面
is_cart()当访问购物车页面时,返回 true。
结账页面
is_checkout()当访问结账页面时,返回 true。
客户账户页面
is_account_page()当访问客户的账户页面时,返回 true。
端点
is_wc_endpoint_url()当浏览 WooCommerce 端点时,返回 true。is_wc_endpoint_url( 'order-pay' )当正在显示用于订单支付的端点页面时。- 依此类推,适用于其他端点...
Ajax 请求
is_ajax()当网页是通过 Ajax 加载时,返回真。
示例
这个例子说明了如何为不同的分类显示不同的内容。
if ( is_product_category() ) {
if ( is_product_category( 'shirts' ) ) {
echo '您好!来看看我们精美的 T 恤,在下面。';
} elseif ( is_product_category( 'games' ) ) {
echo '您好!想来点游戏吗?';
} else {
echo '您好!查看我们下面的产品。';
}
}
如何修复过时的 WooCommerce 模板
模板更新和变更
我们有时会在发布新的 WooCommerce 版本时更新默认模板。 这适用于主要版本(WooCommerce 2.6、3.0 和 4.0),也适用于次要版本(WooCommerce 3.8.0)。
从 WooCommerce 3.3 版本开始,大多数主题与 WooCommerce 配合良好。
我们的面向开发者的博客 会列出每个版本中发生的任何模板文件变更。 如果您使用的是具有较旧模板或较旧版本的 WooCommerce 的主题,或者您修改了模板或正在使用子主题,则您可能需要自行更新模板,或者联系主题作者以获取更新。
大多数主题作者会及时修复主题,因此您只需要更新您的主题即可获得更新后的模板。
或者,您可以选择并使用一个已经使用当前 WooCommerce 模板的不同主题。
如何更新过时的模板
您需要确定要更新哪些模板,备份旧模板,然后恢复任何自定义设置。
- 转到 WooCommerce > 状态 > 系统状态。 滚动到页面底部,您将看到一个列表,其中列出了您的主题/子主题覆盖的模板,以及一条警告消息,表明这些模板需要更新。
- 备份过时的模板。
- 从
wp-content/plugins/woocommerce/templates/[模板路径]复制默认模板,并将其粘贴到您的主题文件夹中,该文件夹位于wp-content/themes/[主题路径]。 - 使用文本编辑器(例如 Sublime、Visual Code、BBEdit、Notepad++)打开您粘贴到主题文件夹中的模板,并将您之前对旧模板所做的任何更改复制到新的、更新后的模板文件中。
我们理解这可能需要花费一些时间。 这就是为什么我们尽量避免更改 WooCommerce 模板,但有时为了不向后兼容是必要的。
常见问题解答
我在哪里可以找到最新版本的 WooCommerce?
如果您正在寻找用于更新的默认模板,您应该使用最新版本的 WooCommerce。 有几种简单的方法可以获取这些模板:
- 如果您的当前 WooCommerce 安装是最新的,请通过 FTP 访问这些文件。
- 您可以在我们的 模板结构文档 中找到每个 WooCommerce 版本的模板。
- 从 WordPress.org 插件页面 下载最新版本。
- 从 GitHub 仓库 下载最新版本。
为什么你们不提供一个按钮,点击一下就可以更新所有内容?
不可能创建一个视频或一键更新功能。 为什么? 因为有成千上万的主题,而且每个主题的编码方式都不同。 并非所有情况都适用相同的解决方案。
主题开发者须知:图片尺寸
注意: 本文档用于开发经典主题(而不是区块主题)。请参考此其他文档,了解区块主题的开发。
为了在您的商品目录中显示图像,WooCommerce 注册了一些图片尺寸,这些尺寸定义了要使用的实际图像尺寸。 这些尺寸包括:
woocommerce_thumbnail- 用于商品“网格”,例如在商店页面上。woocommerce_single- 用于单个商品页面。woocommerce_gallery_thumbnail- 用于在单个商品页面上主图像下方,用于切换图库。
woocommerce_single 显示完整的商品图像,如已上传的图像,默认情况下不进行裁剪。 默认宽度为 600 像素。 woocommerce_gallery_thumbnail 始终以正方形裁剪,默认尺寸为 100x100 像素。 这用于在图库中浏览图像。 woocommerce_thumbnail 默认宽度为 300 像素,正方形裁剪,以使商品网格看起来整洁。 裁剪的长宽比可以由商店所有者自定义。 重要的是要注意,尽管设置了实际的图像宽度,但主题最终可以使用 CSS 更改图像的显示尺寸,并且图像宽度可能受限于商品网格/列的宽度。
主题可以定义图片尺寸
从 WooCommerce 3.3.0 开始,主题可以在声明对 WooCommerce 的支持时,声明应该使用的尺寸。 如果主题定义了图像尺寸(宽度),则商店所有者将无法更改它们,但定义的尺寸应针对主题进行优化。
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 200,
'gallery_thumbnail_image_width' => 100,
'single_image_width' => 500,
) );
当调用 WordPress 函数,例如 wp_get_attachment_image_src,这些函数需要一个图像尺寸时,您应该使用图像尺寸名称,这些名称是:
woocommerce_thumbnailwoocommerce_singlewoocommerce_gallery_thumbnail
商店所有者仍然可以控制长宽比和裁剪(参见下文)。
在自定义设置中自定义图片尺寸
自定义设置包含控制 WooCommerce 中缩略图的选项。
如果主题声明了图片尺寸,则顶部部分将被隐藏,并且仅显示裁剪选项。更改裁剪选项或宽度将更新右侧的预览,以显示效果。更改不会对客户可见,直到自定义设置被“发表”,并且 缩略图已重新生成为新的尺寸。自定义设置中的缩略图裁剪部分允许店主为目录中的图像选择三种裁剪比例设置中的一种:
- 1:1 (方形裁剪)
- 自定义 (店主可以输入自定义长宽比)
- 未裁剪 (保留单个图像的长宽比)
实际的图片尺寸将根据所选的裁剪选项和图片宽度进行计算。
通过钩子更改图片尺寸
虽然主题可以固定图片尺寸在某些宽度,并且店主可以控制宽度和长宽比,但如果您需要更多地控制缩略图尺寸,则有一些可用的钩子。wc_get_image_size 函数由 WooCommerce 使用来获取图片尺寸的尺寸。此函数的返回值会通过一个过滤器传递:woocommerce_get_image_size_{SIZE_NAME_WITHOUT_WOOCOMMERCE_PREFIX}。如果您使用此钩子,您将获得一个类似于以下的尺寸数组:
array(
'width' => 200,
'height' => 200,
'crop' => 1,
)
例如,如果我想将画廊缩略图更改为 150x150 像素的未裁剪图像,可以使用以下代码:
add_filter( 'woocommerce_get_image_size_gallery_thumbnail', function( $size ) {
return array(
'width' => 150,
'height' => 150,
'crop' => 0,
);
} );
我们不建议插件和主题使用此方法,因为它会从店主那里剥夺控制权,并且他们的设置将不被尊重,但此选项可供店主使用。注意: 在更改图片尺寸后,您可能需要 重新生成您的缩略图,以便将新尺寸应用于现有图像。
通过钩子修改 WooCommerce 中使用的图片尺寸
除了上述钩子之外,WooCommerce 中的一些模板函数会通过过滤器处理图片尺寸,因此您可以选择使用除了 WooCommerce 注册的图片尺寸之外的其他尺寸。 以下是一些可用的过滤器:
| 过滤器 | 描述 | 默认值 |
|---|---|---|
single_product_archive_thumbnail_size |
控制产品网格/目录中使用的尺寸。 | woocommerce_thumbnail |
subcategory_archive_thumbnail_size |
控制产品网格/目录中用于分类图片的尺寸。 | woocommerce_thumbnail |
woocommerce_gallery_thumbnail_size |
控制产品画廊中使用的尺寸,位于主图像下方,用于切换到不同的图像。 | 表示 gallery_thumbnail 图像尺寸的数组。 通常为 array( 100, 100 )。 |
woocommerce_gallery_image_size |
控制产品画廊中使用的尺寸。 | woocommerce_single |
woocommerce_gallery_full_size |
控制产品画廊中用于缩放或查看原始尺寸图像的尺寸。 | full |
注意: full 是由 WordPress 注册的尺寸,可以在 设置 > 媒体 中设置。 例如,如果我想将产品画廊缩略图尺寸设置为 WordPress 注册的 thumbnail 尺寸,而不是 woocommerce_gallery_thumbnail,可以使用以下代码片段:
add_filter( 'woocommerce_gallery_thumbnail_size', function( $size ) {
return 'thumbnail';
} );
注意: 上述钩子由 WooCommerce 核心使用。 如果主题有自定义模板文件或使用自己的函数来输出图像,则这些过滤器可能未被使用。
如何设置和使用子主题
注意: 本文档旨在用于创建和使用经典子主题。有关创建子块主题的全面指南以及了解经典主题和块主题之间的区别,请参阅 WooCommerce 块主题开发 和 WordPress 块子主题开发。
有时,您可能需要自定义您的主题或 WooCommerce,而这些自定义超出了选项所能提供的范围。这些指南将教您如何通过使用子主题来定制您的网站的基本方法。
什么是子主题?
在开始之前,重要的是您要了解什么是子主题。简而言之,子主题是在父主题之上的一个层,允许您进行修改,而无需从头开始开发一个新的主题。使用子主题的主要原因有两个:
- 主题开发者可以使用子主题来提供主题的变体,类似于我们对 Storefront 子主题 所做的那样。
- 开发者可以使用子主题来托管对父主题或网站上任何插件的自定义,因为子主题的优先级高于插件和父主题。
备份
在自定义网站之前,您应该始终确保备份您的网站,以防出现任何问题。更多信息请访问:备份 WordPress 内容。
准备开始
要开始,我们需要准备一个子主题。
创建子主题
首先,我们需要为我们的子主题创建一个新的样式表。创建一个名为 style.css 的新文件,并将以下代码放入其中:
/*
Theme Name: Child Theme
Version: 1.0
Description: Child theme for Woo.
Author: Woo
Author URI: https://woocommerce.com
Template: themedir
*/
接下来,我们需要更改 Template 字段,使其指向我们安装的 WooTheme。在此示例中,我们将使用 Storefront 主题,该主题安装在 wp-content/themes/storefront/ 目录下。结果将如下所示:
/*
Theme Name: Storefront Child
Version: 1.0
Description: Child theme for Storefront.
Author: Woo
Author URI: https://woocommerce.com
Template: storefront
*/
/* --------------- 主题自定义从此处开始 ----------------- */
注意: 对于 Storefront,您无需使用 PHP 从主题的 functions.php 文件中调用任何父主题的样式文件,也不需要将这些样式文件通过 @import 导入到子主题的 style.css 文件中,因为主要的 Storefront 主题已经为您完成了这些操作。
对于 Storefront,一个子主题只需要一个空白的 functions.php 文件和一个 style.css 文件即可开始运行。
上传和激活
您可以选择通过 FTP 客户端或使用 WordPress 中的“添加新主题”选项来上传子主题。
- 通过 FTP。 如果您使用 FTP,这意味着您可以直接访问您的网站的文件夹。 这意味着您需要 FTP 访问权限,以便将新的子主题上传到您的服务器。 如果您没有此权限,请联系您的主机提供商,他们可以为您提供 FTP 登录信息,然后下载一个 FTP 客户端程序来上传您的文件。
- 通过 WP 仪表盘。 如果您将子主题文件夹压缩成一个 .zip 文件,您可以直接从 WordPress > 外观 > 主题 > 添加新 部分将其上传到您的网站。
完成此操作后,您的子主题将被上传到 wp-content/themes/ 目录下的一个新文件夹,例如 wp-content/themes/storefront-child/。 上传完成后,您可以进入 WP 仪表盘 > 外观 > 主题 并激活子主题。
自定义设计和功能
您的子主题现在已准备好进行修改。 目前,它不包含任何自定义设置,因此让我们看看一些示例,了解如何在不修改父主题的情况下自定义子主题。
设计自定义
让我们一起做一个示例,更改网站标题的颜色。 将以下代码添加到您的 /storefront-child/style.css 文件中:
.site-branding h1 a {
color: red;
}
保存文件并在浏览器中刷新后,您将看到网站标题的颜色已更改!
模板更改
注意: 这不适用于 Storefront 子主题。 对 Storefront 子主题文件的任何修改将在更新时丢失。 建议您不要直接修改 Storefront 子主题的文件,而是将代码片段添加到自定义插件中。 我们创建了一个插件来完成此操作。 免费下载 Theme Customizations。
但是,还有更多! 您也可以对主题文件夹中的模板文件 (*.php) 执行相同的操作。 例如,如果您想修改页眉中的某些代码,则需要将 header.php 从父主题文件夹 wp-content/themes/storefront/header.php 复制到子主题文件夹 wp-content/themes/storefront-child/header.php。 将其复制到子主题后,编辑 header.php 并自定义您想要修改的任何代码。 子主题中的 header.php 将被使用,而不是父主题中的 header.php。
同样适用于 WooCommerce 模板。 如果您在子主题中创建一个名为 "WooCommerce" 的新文件夹,您可以修改该文件夹中的 WooCommerce 模板,使其与您网站的整体设计更加一致。 关于 WooCommerce 模板结构的更多信息 请参见此处。
功能变更
注意: 您的子主题中的 functions.php 应该为空,并且不应包含任何来自父主题的 functions.php 中的内容。
您的子主题中的 functions.php 会在父主题的 functions.php 之前加载。 如果父主题中的函数是可替换的,那么您可以将该函数从父主题复制到子主题的 functions.php 中,并使其替换掉父主题中的函数。 唯一的条件是父主题的函数必须是可替换的,这意味着它被包含在一个条件 if 语句中,例如:
if ( ! function_exists( "parent_function_name" ) ) {
parent_function_name() {
...
}
}
如果父主题的函数是可替换的,您可以将其复制到子主题的 functions.php 中,并根据需要修改该函数。
模板目录与样式目录
WordPress 在子主题中对某些内容的处理方式有所不同。 如果您在子主题中有一个模板文件,则需要修改 WordPress 如何包含文件。 get_template_directory() 将引用父主题。 要使其使用子主题中的文件,您需要使用 get_stylesheet_directory()。
子主题支持
虽然我们提供基本的子主题支持,这些问题通常可以轻松解答,但它仍然属于主题定制的范畴,因此请参考我们的 支持政策,以了解我们提供的支持范围。 我们强烈建议任何对子主题感到困惑的用户,请访问 WordPress 论坛 寻求帮助。
示例子主题
下载位于本文顶部的示例子主题,以开始使用。 将子主题放置在您的 wp-content/themes/ 文件夹中,与您的父主题一起。
模板结构 & 通过主题覆盖模板
注意 本文档中提到了使用 PHP 模板的经典主题。如果您正在使用区块主题,并且使用 HTML 模板,请查看区块主题的主题文档。 概述
概述
WooCommerce 模板文件包含您商店前端和 HTML 邮件的标记和模板结构。
模板列表
您 WooCommerce 站点的各种模板文件可以通过 FTP 客户端或您的主机文件管理器在 /wp-content/plugins/woocommerce/templates/ 目录中找到。 另外,您可以在 我们的 GitHub 仓库中找到模板文件。
注意:如果您正在查找旧版本的模板文件,您可以在以下路径中找到它们:
- 6.0.0 及更高版本:
https://github.com/woocommerce/woocommerce/tree/[VERSION_NUMBER]/plugins/woocommerce/templates- 例如,要查找 WooCommerce 9.4.0 的模板文件,请访问 https://github.com/woocommerce/woocommerce/tree/9.4.0/plugins/woocommerce/templates。
- 6.0.0 之前的版本:
https://github.com/woocommerce/woocommerce/tree/[VERSION_NUMBER]/templates- 例如,要查找 WooCommerce 5.9.0 的模板文件,请访问 https://github.com/woocommerce/woocommerce/tree/5.9.0/templates。
通过 Hooks 修改模板
当您打开一个模板文件时,您会发现它们都包含 hooks,这些 hooks 允许您添加/移动内容,而无需直接编辑模板文件本身。 Hooks 是一种让一段代码与另一段代码在特定的、预定义的点进行交互/修改的方式。 这种方法允许实现一个代码片段,该代码片段“hook”到特定的主题位置。 这样做可以避免升级问题,因为模板文件可以完全保持不变,并且不需要配置子主题。
让我们看一下 /wp-content/plugins/woocommerce/templates/emails/admin-new-order.php 文件,看看 hook 看起来是什么样的。 从第 30 行开始,我们看到以下代码,该代码负责生成 新订单 电子邮件的订单详情部分。
/*
* @hooked WC_Emails::order_details() 显示订单详情表。
* @hooked WC_Structured_Data::generate_order_data() 生成结构化数据。
* @hooked WC_Structured_Data::output_structured_data() 输出结构化数据。
* @since 2.5.0
*/
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
上面的代码输出图像中红色区域的块,该块是商店管理员在网站上成功下单后收到的 新订单 电子邮件:

以下代码可以作为构建所需功能的起点。 然后,可以将它添加到代码片段插件中,以修改模板中该特定位置的输出,而无需编辑模板本身。 同样适用于其他 hooks,无论它们出现在模板的哪个位置。
add_action( 'woocommerce_email_order_details', 'my_custom_woo_function');
function my_custom_woo_function() {
/* 您的代码放在此处 */
}
通过编辑文件修改模板
直接在插件或父主题中编辑文件会带来风险,可能导致错误,甚至使网站停止运行。更重要的是,通过这种方式进行的任何更改,在插件或主题更新时都会消失;因为更新过程会完全删除旧版本,并用新的、更新的版本替换它。
因此,推荐的方法是设置一个子主题,这样可以创建一个安全的目录,用于进行覆盖修改,这些修改不会被自动更新。
在这个例子中,我们给子主题命名为 storefront-child。有了 storefront-child,就可以通过覆盖的方式进行升级安全的修改。将模板复制到子主题中的一个目录中,目录名称为 /storefront-child/woocommerce/,保持与原始文件相同的目录结构,但删除 /templates/ 子目录。
要覆盖示例中的管理员订单通知,请将 wp-content/plugins/woocommerce/templates/emails/admin-new-order.php 复制到 wp-content/themes/storefront-child/woocommerce/emails/admin-new-order.php。
复制的文件现在将覆盖 WooCommerce 的默认模板文件,因此您可以对复制的文件进行任何您希望的更改,并在最终输出中看到这些更改。
主题设计和用户体验指南
本指南涵盖一般准则和最佳实践,旨在确保您的主题体验符合电子商务行业标准,并与 WooCommerce 共同提供卓越的在线购物体验,从而最大化销售额,确保易用性,实现无缝集成,并提升用户体验。
我们建议您查阅 WordPress 的 UI 最佳实践,以确保您的主题符合 WordPress 主题的要求。
请确保您的主题适用于目前在 WooCommerce 主题商店 中提供的至少一个行业。 重要的是,主题在设计上应具有足够的原创性和独特性,同时保持熟悉感,以便在 WooCommerce 主题商店中脱颖而出。 您的主题应避免复制 WooCommerce 主题商店或其他 WordPress 主题市场中已有的主题。
设计
高质量的设计是在线商店的重要组成部分,这主要由主题设计和内容驱动。 主题的设计应简洁、一致、不杂乱、令人难忘、直观、高效且实用。 在为 WooCommerce 设计新主题时,应特别注意以下几点:
布局
主题的布局应符合行业标准,包括层级结构、流程、内容平衡和留白。
主题作者必须确保商店页面(商店、产品页面、分类、购物车、结账、个人资料页面等)与主题无缝集成,因为它们是 WooCommerce 主题的核心。
主题应完全正常运行,并经过优化,可在常见的设备类型(如笔记本电脑、平板电脑和智能手机)上访问。
排版
主题应提供优雅且易于阅读的字体组合,以促进舒适的阅读体验。
所有页面和设备类型都应采用一致且和谐的字体大小、线宽和间距。
主题的排版应包含少量相互补充的字体,通常不超过两种。
应使用正确的首字母大写,避免全部大写(除非是某些 UI 元素,如按钮、标签等)。
图标
主题中使用的图标应直接表达其所代表的操作/情况,并且在大小、位置和颜色方面应保持一致。
颜色
主题必须遵循所有 UI 元素和页面的和谐且一致的配色方案。 配色方案应包含少量颜色:
- 一种主要/强调色
- 一种或两种与主要色互补的辅助色
- 纯色(白色、黑色、灰色)
文本和图形 UI 组件中使用的颜色必须符合 WCAG AA 兼容性级别 或更高。
模式
主题必须采用一套一致的模式,并在所有网页中使用,例如:
- 导航、侧边栏、页脚
- 内容块(标题、段落、列表、产品详情、评论、图片展示等)
- 表单的结构和元素(字段、下拉菜单、按钮等)
- 表格
- 列表
- 通知
可访问性
主题必须符合 Web 内容可访问性指南 (WCAG)。完全符合 WCAG 2.0 需要付出很多努力;至少要达到 AA 级别的可访问性。
有关可访问性的更多信息,请查看 WordPress 可访问性快速入门指南。
自定义
主题必须依赖于自定义工具来进行任何初始设置。不允许使用特定的引导流程。
主题支持的任何自定义功能,例如布局选项、附加功能、块选项等,都应通过自定义工具或块设置(适用于主题中包含的块)提供。
主题不应捆绑或要求安装额外的插件/扩展(或框架),这些插件/扩展提供额外的选项或功能。有关自定义的更多信息,请查看 WordPress 主题自定义 API。
在激活时,主题不应通过将用户引导到其他页面来覆盖 WordPress 主题激活流程。
品牌
主题不得包含任何品牌或指向主题作者的引用,这些内容会干扰在线商店的正常运行。主题作者可以在主题页脚中包含指向其网站的链接。不允许进行联盟营销。
界面应仅关注用户体验,不允许在管理界面中使用通知、横幅、大型徽标或任何促销材料。
演示和示例内容
提交主题时,作者必须提供一种方式来展示和测试主题。示例内容/演示应避免使用自定义图形/资源,这些资源不会包含在交付内容中,以避免商家混淆和期望落空(例如:使用徽标、插图)。在为特定领域创建主题时,作者应考虑使用与该领域相关的示例内容。
所有图像和文本都应适合所有年龄段/家庭友好。主题作者应考虑使用包含各种年龄、国籍等的图像。主题应避免使用看起来像“库存照片”的图像。
主题必须以符合所有必要资产(例如图像、字体、图标等)的许可证的方式进行分发。
缩略图重新生成
WooCommerce 3.3 引入了缩略图重新生成功能。 过去,当图片尺寸设置发生更改时,您需要安装一个外部插件,然后让该插件重新生成所有 WordPress 图片缩略图,才能使更改可见。
新的图片重新生成功能,以及在自定义器中引入 WooCommerce 图片设置,现在确保您在对商店图片设置进行更改时,可以在自定义器中实时预览这些更改。
工作原理
当您在自定义器中更改图片尺寸/长宽比时,或者当您的主题更改图片尺寸时,WC 会检测到这些更改并排队一个后台重新生成任务。 触发此操作的两种情况是:
- 在自定义器中发布设置
- 切换主题
在自定义器中,由于我们的实时图片重新生成功能,您可以预览尺寸更改。 这些更改不会持久保存到实际网站,直到您点击“发布”。
后台任务和 BasicAuth
如果您的网站受到 BasicAuth 保护,则异步请求和后台进程将无法完成。 这是因为 WP Background Processing 依赖于 WordPress HTTP API,而 WordPress HTTP API 要求您将 BasicAuth 凭据附加到请求中。
您可以通过一个代码片段传递这些凭据,请参阅:BasicAuth 文档。
查看后台重新生成日志
要查看后台图片重新生成的日志,请转到 WooCommerce > 状态 > 日志,然后从下拉列表中选择 wc-background-regeneration 日志。
此日志文件将列出已处理的图片以及任务完成或取消的时间。
取消后台重新生成任务
从 WooCommerce 3.3.2 开始,当后台图片重新生成正在运行时,您将看到一个管理员通知。 在此通知中有一个链接,用于取消该任务。
取消该任务将阻止生成更多缩略图。 如果您的目录中显示的图片尺寸不正确,您需要手动运行缩略图重新生成(可以使用我们的工具,也可以使用另一个插件,例如 [Regenerate Thumbnails](https://en-gb.wordpress.org/plugins/regenerate-thumbnails/)。
CDN 插件
大多数 CDN 插件会监听 WordPress 核心钩子,并在创建缩略图后将其上传到其服务。 我们的后台图片重新生成代码将继续支持此功能。 由于在生成过程中将图片上传到第三方服务,因此生成速度可能会变慢。
如何禁用背景图像重新生成
woocommerce_background_image_regeneration 过滤器可用于完全禁用背景图像重新生成。 示例代码:
add_filter( 'woocommerce_background_image_regeneration', '__return_false' );
一旦禁用,如果您更改了图片尺寸设置并需要新的缩略图,您需要使用其他工具手动重新生成缩略图。
或者,您可以使用 Jetpack Photon 模块,该模块可以在运行时进行图像调整大小,并且从 WooCommerce 3.3.2 开始,它将替代背景图像重新生成功能。
使用 Jetpack Photon 代替
Jetpack 是 Automattic 开发的一个插件,Automattic 也是 WordPress.com 的开发商。 它可以为您的自托管 WordPress 站点提供一些与 WordPress.com 托管站点相同的可用功能。
Photon 模块 允许您的站点上的图像从 WordPress.com 的全球内容分发网络 (CDN) 提供,这应该可以加快图像的加载速度。
Photon 可以即时创建缩略图,这意味着您将永远不需要使用我们的背景图像重新生成功能。
如何修复过时的 WooCommerce 模板
模板更新和变更
我们有时会在发布新的 WooCommerce 版本时更新默认模板。 这适用于主要版本(WooCommerce 2.6、3.0 和 4.0),也适用于次要版本(WooCommerce 3.8.0)。
从 WooCommerce 版本 3.3 开始,大多数主题与 WooCommerce 配合良好。
我们的面向开发者的博客 会列出每个版本中发生的任何模板文件变更。 如果您使用的是具有较旧模板或较旧版本的 WooCommerce 的主题,或者您修改了模板或正在使用子主题,则您可能需要自行更新模板,或者联系主题作者以获取更新。
大多数主题作者会及时修复主题,因此您只需要更新您的主题即可获得更新后的模板。
或者,您可以选择并使用一个已经使用当前 WooCommerce 模板的不同主题。
如何更新过时的模板
您需要确定要更新哪些模板,备份旧模板,然后恢复任何自定义设置。
- 转到 WooCommerce > 状态 > 系统状态。 滚动到页面底部,您将看到一个列表,其中列出了您的主题/子主题覆盖的模板,以及一条警告消息,表明这些模板需要更新。
- 备份过时的模板。
- 从
wp-content/plugins/woocommerce/templates/[path-to-the-template]复制默认模板,并将其粘贴到您的主题文件夹中,该文件夹位于wp-content/themes/[path-to-theme]。 - 使用文本编辑器(例如 Sublime、Visual Code、BBEdit、Notepad++)打开您粘贴到主题文件夹中的模板,并将您在以前的模板中所做的任何更改复制到新的、更新后的模板文件中。
我们理解这可能需要花费一些时间。 这就是为什么我们尽量避免更改 WooCommerce 模板,但有时为了不向后兼容是必要的。
常见问题解答
我在哪里可以找到最新版本的 WooCommerce?
如果您正在寻找用于更新的默认模板,您应该使用最新版本的 WooCommerce。 有几种简单的方法可以获取这些模板:
- 如果您的当前 WooCommerce 安装是最新的,请通过 FTP 访问这些文件。
- 您可以在我们的 模板结构文档 中找到每个 WooCommerce 版本的模板。
- 从 WordPress.org 插件页面 下载最新版本。
- 从 GitHub 仓库 下载最新版本。
为什么你们不提供一个按钮,点击一下就可以更新所有内容?
不可能制作一个视频或一键更新功能。 为什么? 因为有成千上万的主题,而且每个主题的代码都不同。 并非所有情况都适用。
支付按钮布局
定义支付按钮与其容器之间的位置和对齐方式,保持相同的层级结构,并在按钮之间保持一致的间距。
产品页面
在水平或垂直布局中,正确地将支付按钮放置在“加入购物车”按钮的旁边或下方。

购物车
在垂直布局中,正确地将支付按钮放置在“继续结账”按钮的上方。不要将支付按钮放置在“继续结账”按钮的下方或按钮之间。

快速结账
在水平布局中,保持支付按钮的大小和间距一致。如果需要第二行按钮,请将按钮左对齐。

移动端视图
移动端上的快速支付按钮应占据全宽。不要使用快速支付按钮的边框,因为它会减少显示区域。

留白
在支付按钮的四周,保持最小的留白区域。留白区域会根据按钮的大小进行调整。

支付按钮的大小和结构
支付按钮在视觉外观上必须与其他购物体验中的按钮保持一致。
支付按钮的高度范围从 40 像素(小)到 55 像素(大)。默认按钮高度为 48 像素。以下预设可用于按钮高度。
- 小:高度 40 像素
- 默认:高度 48 像素
- 大:高度 55 像素
结构
支付按钮最多由三个元素组成:一个按钮组件、支付标志和可选的标签。

不要在按钮的表面区域之外放置任何文本。

布局和间距
标签和支付标志之间的间距以及周围的间距,会根据按钮的大小进行调整。

自适应高度
按钮的高度可以根据主题的需求进行调整。

按钮大小
使支付按钮的大小与其他支付按钮相同,不能大于或小于其他支付按钮,包括“加入购物车”和“继续结账”等 CTA 按钮。

按钮宽度
为所有支付按钮使用相同的宽度。不要使宽度大于或小于其他支付按钮。

最小宽度
按钮具有最小宽度,以确保可读性。

请遵循每种支付按钮大小的最小宽度。不要将支付按钮压缩到单行中。

按钮形状
为所有支付按钮使用相同的圆角半径。不要使圆角半径大于或小于其他支付按钮。
- 默认圆角半径:4 像素
- 最大圆角半径:按钮高度的一半

按钮标签
提供变体按钮,以满足商家的需求和支付体验。
- Buy
- Pay
- Donate
- Book
- Checkout
- Subscribe
- Continue
- Order
- Icon only
按钮标签应采用句首大写形式,即仅将第一个单词的首字母大写。

支付按钮样式
根据站点的主题,使用合适的按钮样式。

深色
适用于白色或浅色背景。不要在黑色或深色背景中使用。

浅色
适用于深色背景。不要在白色或浅色背景中使用。

带轮廓的浅色
适用于白色或浅色背景,但这些背景提供的对比度不足时使用。不要在深色或饱和背景中使用。

按钮样式和规范
按钮应包含以下状态:静止、加载中、激活和加载上下文。有关更多指导,请遵循通用的 Woo 辅助功能指南。

支付集成与设置
支付集成
插件作者应积极引导商家在安装并激活插件后完成设置。
第三方集成
对于使用 OAuth 或第三方体验从商家处获取授权的插件,商家会点击一个链接来设置您的插件,该链接会重定向到插件的集成页面。
商家将被重定向到支付插件以完成配置,并在此步骤中完成任何必需的身份验证。
例如:
- 提示商家登录或创建与支付提供商的帐户。
- 提示商家完成计费计划、支付或通知的配置。
手动设置
如果需要手动输入 API 密钥,请设计设置过程尽可能简单,理想情况下,使用一个引导式安装向导。
配置与设置
请遵循 Woo 用户体验指南,关于 [设置](docs/user-experience-guidelines/ux-guidelines-payments/ /docs/extensions/ux-guidelines-extensions/settings) 和 [导航](docs/user-experience-guidelines/ux-guidelines-payments/ /docs/extensions/ux-guidelines-extensions/navigation)。
包含合理的默认设置,以最大限度地减少用户的配置工作量。
在商家完成插件集成的所有必要操作后,商家将被重定向回 Woo 后台,以选择要提供的付款方式并配置插件的其他设置。
如果您在插件中提供多种付款方式,请清晰地向商家展示这些选项,并提供指示哪些付款方式已启用的方式。

如果由于任何原因,某个付款方式不可用,请提供清晰且信息丰富的错误消息,以帮助用户诊断和解决问题。
您的插件需要通知商家,插件已准备好处理支付。在此之前,在插件设置中显示一个内联警告通知,以提醒商家。请勿为警告通知实现顶层横幅。

可访问性
您的主题必须符合 WordPress 可访问性编码规范。
要了解更多关于可访问性的信息,请查看 WordPress 可访问性快速入门指南。
品牌标识
主题不得包含任何品牌标识或对主题作者的引用,这些内容不得出现在可能干扰在线商店正常运行的位置。主题作者可以在主题页脚中添加指向其网站的链接。不允许使用联盟链接。
界面应完全专注于用户体验。不允许在管理界面中使用通知、横幅、大型Logo或任何宣传材料。
自定义
本指南的此页面仅适用于非区块主题的开发。有关区块主题开发的更具体指导,请参考WordPress 开发者区块主题指南。
所有主题都必须依赖自定义器进行任何类型的初始设置。不允许使用任何特定的引导流程。
主题支持的任何自定义功能,例如布局选项、附加功能、块选项等,都应通过自定义器提供,或者对于包含在主题中的块,应通过块设置提供。
主题不应捆绑或要求安装任何额外的插件/扩展(或框架),这些插件/扩展提供额外的选项或功能。有关自定义的更多信息,请查看WordPress 主题自定义 API。
激活时,主题不应通过将用户引导到其他页面来覆盖 WordPress 主题激活流程。
演示和示例内容
当作者提交主题时,必须提供一种方式来展示和测试该主题。 示例内容/演示应避免使用将在最终交付物中不存在的自定义图形/资源,以避免造成商家困惑和期望落空(例如:使用徽标、插图)。 当作者为特定领域创建主题时,应考虑使用与该领域相关的示例内容。
所有图像和文本应适合所有年龄段/家庭友好。 主题作者应考虑使用包含各种年龄、国籍等的图像。 主题应避免使用看起来像“库存摄影”的图像。
该主题必须分发并清除所有必要的资产许可证,例如图像、字体、图标等。
品牌形象
高质量的设计是网上商店的重要组成部分,这主要取决于主题的设计和内容。主题的设计应简洁、一致、不杂乱、令人难忘、直观、高效且实用。在为 WooCommerce 设计新的主题时,应特别注意以下几点:
布局
主题的布局应符合行业标准,包括层级结构、流程、内容平衡和留白。
主题作者必须确保商店页面(商店、产品页面、分类、购物车、结账、个人资料页面等)与主题无缝集成,因为它们是 WooCommerce 主题的核心。
主题应完全可用,并经过优化,可在常见的设备类型(如笔记本电脑、平板电脑和智能手机)上访问。
排版
主题应提供优雅且易于阅读的字体组合,以提供舒适的阅读体验。
所有页面和设备类型都必须采用一致且和谐的字体大小、线宽和间距。
主题的排版应由少量相互补充的字体组成,通常不超过两种。
应使用正确的首字母大写,避免全部大写(除非是某些用户界面元素,如按钮、选项卡等)。
图标
主题中使用的图标应直接表达其所代表的动作/情况,并且在尺寸、位置和颜色方面应保持一致。
颜色
主题必须遵循和谐且一致的颜色方案,应用于用户界面元素和所有页面。颜色方案应包含少量颜色,包括:
- 一种主要的/强调的颜色
- 一种或两种与主要颜色互补的辅助颜色
- 纯色(白色、黑色、灰色)
文本和图形用户界面组件中使用的调色板必须符合 WCAG AA 兼容性级别 或更高。
模式
主题必须采用一组一致的模式,这些模式应在所有页面中使用,例如:
- 导航、侧边栏、页脚
- 内容块(标题、段落、列表、产品详情、评论、图片展示等)
- 表单的结构和元素(字段、下拉菜单、按钮等)
- 表格
- 列表
- 通知
可访问性
您的主题必须符合 WordPress 可访问性编码规范。
要了解更多关于可访问性的信息,请查看 WordPress 可访问性快速入门指南。
品牌标识
主题不得包含任何品牌标识或对主题作者的引用,这些内容不得出现在可能干扰在线商店正常运行的位置。主题作者可以在主题页脚中添加指向其网站的链接。不允许使用联盟链接。
界面应完全专注于用户体验。不允许在管理界面中使用通知、横幅、大型Logo或任何宣传材料。
自定义
本指南的此页面仅适用于非区块主题的开发。有关区块主题开发的更具体指导,请参考WordPress 开发者区块主题指南。
所有主题都必须依赖自定义器进行任何类型的初始设置。不允许使用任何特定的引导流程。
主题支持的任何自定义功能,例如布局选项、附加功能、块选项等,都应通过自定义器提供,或者对于包含在主题中的块,应通过块设置提供。
主题不应捆绑或要求安装任何额外的插件/扩展(或框架),这些插件/扩展提供额外的选项或功能。有关自定义的更多信息,请查看WordPress 主题自定义 API。
激活时,主题不应通过将用户引导到其他页面来覆盖 WordPress 主题激活流程。
演示和示例内容
当作者提交主题时,必须提供一种方式来展示和测试该主题。 示例内容/演示应避免使用将在最终交付物中不存在的自定义图形/资源,以避免造成商家困惑和期望落空(例如:使用徽标、插图)。 当作者为特定领域创建主题时,应考虑使用与该领域相关的示例内容。
所有图像和文本应适合所有年龄段/家庭友好。 主题作者应考虑使用包含各种年龄、国籍等的图像。 主题应避免使用看起来像“库存摄影”的图像。
该主题必须分发并清除所有必要的资产许可证,例如图像、字体、图标等。
WooCommerce CLI 常见问题
常见问题
什么是 WooCommerce CLI?
- WooCommerce CLI (WC-CLI) 是一个命令行界面,用于管理 WooCommerce 的设置和数据。它提供了一种快速高效的方法来执行许多通常需要通过 WordPress 后台手动操作的任务。
我如何安装 WooCommerce CLI?
- WooCommerce CLI 从版本 3.0.0 开始包含在 WooCommerce 中。 确保您已安装 WooCommerce 3.0.0 或更高版本,您将自动访问 WC-CLI。
WooCommerce CLI 和 WP-CLI 有什么不同?
- WooCommerce CLI 是 WP-CLI 的一部分,专门用于 WooCommerce。 虽然 WP-CLI 涉及一般的 WordPress 管理,但 WC-CLI 专注于 WooCommerce 相关的任务。
技术问题
我如何备份我的 WooCommerce 数据?
- WC-CLI 不直接处理备份。 但是,您可以使用其他 WP-CLI 命令来导出 WooCommerce 数据,或者依赖 WordPress 备份插件。
我可以使用 CLI 更新 WooCommerce 设置吗?
- 是的,您可以使用 WC-CLI 更新许多 WooCommerce 设置。 例如,要更新商店的电子邮件设置,您可以使用类似于
wp wc setting update [options]的命令。
故障排除
为什么我收到“权限被拒绝”的错误?
- 这种错误通常发生在您的用户角色没有必要的权限时。 确保您使用的是具有管理权限的帐户。
如果命令未按预期工作,我该怎么办?
- 检查是否有拼写错误,并使用
--help验证命令语法。 如果问题仍然存在,请参阅命令参考或寻求 WooCommerce 社区的支持。
如果我在使用命令时收到 404 错误,我该怎么办?
如果收到类似于 Error: Sorry, you cannot list resources. {"status":401} 的 401 错误,则表示您正在尝试在未进行身份验证的情况下使用该命令。 从 3.0 版本开始,WooCommerce CLI 要求您提供一个用户来执行操作。 使用 --user 标志传递您的用户 ID。
我正在尝试更新 X 的列表,但它没有保存。
某些“列表”实际上是对象。 例如,如果您想为产品设置分类,则 REST API 期望的是一个对象数组。
要设置此项,您可以使用如下 JSON:
wp wc product create --name='Product Name' --categories='[ { "id" : 21 } ]' --user=admin
高级用法
我可以使用 WooCommerce CLI 进行批量产品更新吗?
- 是的,WC-CLI 非常适合批量操作。 您可以使用脚本循环遍历产品列表并应用更新。
我如何使用 WC-CLI 处理复杂的查询?
- WC-CLI 支持各种参数和过滤器,您可以使用它们来构建复杂的查询。 将这些与 shell 脚本结合使用可以获得强大的结果。
WooCommerce CLI 概述
WooCommerce CLI 简介
WooCommerce CLI (WC-CLI) 提供了一种高效的方式,可以通过命令行管理 WooCommerce (WC) 商店。该工具是 WC 从版本 3.0.0 开始的一部分,并利用了 WC REST API 的功能。这意味着可以通过命令行执行大多数可以通过 REST API 实现的任务。
有关 WC 版本 2.5 和 2.6 的 CLI 的文档,请访问 旧版 CLI 命令。
关于 WP-CLI
WP-CLI 是一组强大的命令行工具,用于管理 WordPress 安装。您可以更新插件、配置多站点安装,以及更多操作,而无需使用 Web 浏览器。 更多信息,请访问 官方 WP-CLI 网站。
开始使用 WooCommerce CLI
要开始使用 WC-CLI,请确保已安装 WP-CLI,并且正在运行 WooCommerce 3.0.0 或更高版本。 CLI 命令通过 wp wc 命令访问。 要查看所有可用命令的完整列表,请在命令行界面中键入 wp wc。
有关命令及其用法的具体信息,请参阅“命令参考”部分。 “操作指南”提供了一种实用的方法来执行常见任务,非常适合那些是 WC-CLI 的新手或正在寻找快速解决方案的人。
附加资源
对于那些有兴趣进一步探索的人,以下资源可能很有帮助:
如何使用 WooCommerce CLI
简介
本指南旨在帮助初学者使用 WooCommerce CLI (WC-CLI) 通过命令行管理 WooCommerce 商店。
快速开始
- 确保已安装 WP-CLI,并且 WooCommerce 的版本至少为 3.0.0。
- 检查 WC-CLI 是否可用:
wp wc --info
通用命令结构
WC-CLI 命令的通用语法如下:
wp wc [command] [options]
要获取任何特定命令的详细帮助,请使用:
wp wc [command] --help
基本任务
1. 列表显示产品
要列出 WooCommerce 商店中的所有产品:
wp wc product list
2. 创建新产品
要创建新产品:
wp wc product create --name="New Product" --type="simple" --regular_price="19.99"
3. 更新产品
要更新现有产品(例如,产品 ID 123):
wp wc product update 123 --regular_price="24.99"
4. 删除产品
要删除产品(例如,产品 ID 123):
wp wc product delete 123 --force
要查看完整的 WC-CLI 命令列表,请查看我们的 WC-CLI 命令 文档。
WooCommerce CLI 命令
概述
本文档是 WooCommerce 命令行界面 (WC-CLI) 命令的综合参考。它包含每个命令的语法、选项和简要描述。这些命令适用于 WooCommerce 版本 3.0.0 及更高版本。
通用命令结构
WC-CLI 命令的通用语法如下:
wp wc [命令] [选项]
要获取任何特定命令的详细帮助,请使用:
wp wc [命令] --help
命令
wc blueprint
wc blueprint import [结构化数据路径]
--show-messages- 显示调试信息。支持的日志级别:all, error, info, debug。
wc blueprint export [保存到文件名]
--steps- 要导出的步骤名称。
wc com
wc com extension list
--format- 以特定格式渲染输出。
默认:table
选项:table, csv, json, yaml
--fields- 限制输出到特定的对象字段。
默认:all
选项:product_slug, product_name, auto_renew, expires_on, expired, sites_max, sites_active, maxed
wc com extension install [扩展]
--extension- 从可用扩展中安装一个插件。接受插件别名。--force- 如果设置,该命令将覆盖已安装的任何扩展版本,而无需提示确认。--activate- 如果设置,安装后,该命令将激活插件。--activate-network- 如果设置,插件将在安装后立即进行网络激活。--insecure- 如果 TLS 握手失败,则重试下载,无需证书验证。注意:这会使请求容易受到 MITM 攻击。
wc customer
wc customer list
--context- 请求的范围;确定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的项数。默认为 100 项。--search- 限制结果,仅包含匹配的字符串。--exclude- 确保结果集排除特定的 ID。--include- 限制结果集为特定的 ID。--offset- 通过特定数量的项来偏移结果集。--order- 按照升序或降序对排序属性进行排序。--orderby- 按照对象属性对集合进行排序。--email- 限制结果集为具有特定电子邮件地址的资源。--role- 限制结果集为具有特定角色的资源。--fields- 限制响应为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc customer create
--email- 新用户的 Email 地址。(必需)--first_name- 客户的 名。--last_name- 客户的 姓氏。--username- 新用户的 用户名。--password- 新用户的 密码。(必需)--billing- 账单地址 数据列表。--shipping- 配送 地址 数据列表。--meta_data- 元数据。--porcelain- 当操作成功时,仅输出 ID。
wc customer get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc customer update [id]
--id- 资源的唯一标识符。--email- 客户的 Email 地址。--first_name- 客户的 名。--last_name- 客户的 姓氏。--username- 客户的 登录名。--password- 客户的 密码。--billing- 账单地址 数据列表。--shipping- 配送 地址 数据列表。--meta_data- 元数据。--porcelain- 当操作成功时,仅输出 ID。
wc customer delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为资源不支持放入回收站。--reassign- 用于重新分配帖子的 ID。--porcelain- 当操作成功时,仅输出 ID。
wc customer_download
wc customer_download list <customer_id>
--customer_id- 资源的唯一标识符。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc order_note
wc order_note list <order_id>
--order_id- 订单 ID。--context- 发送请求的范围;决定响应中包含的字段。--type- 限制结果为客户或内部备注。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc order_note create <order_id>
--order_id- 订单 ID。--note- 订单备注内容。(必需)--customer_note- 如果为 true,则备注将显示给客户,并且他们将收到通知。如果为 false,则备注仅供管理员参考。--porcelain- 当操作成功时,仅输出 ID。
wc order_note get <order_id> [id]
--id- 资源的唯一标识符。--order_id- 订单 ID。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc order_note delete <order_id> [id]
--id- 资源的唯一标识符。--order_id- 订单 ID。--force- 必须设置为 true,因为该资源不支持放入回收站。--porcelain- 操作成功时,仅输出 ID。
wc payment_gateway
wc payment_gateway list
--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc payment_gateway get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc payment_gateway update [id]
--id- 资源的唯一标识符。--title- 在结账页面上显示的支付网关标题。--description- 在结账页面上显示的支付网关描述。--order- 支付网关的排序顺序。--enabled- 支付网关的启用状态。--settings- 支付网关的设置。--porcelain- 操作成功时,仅输出 ID。
wc product
wc product list
--context- 请求的作用域;决定响应中包含的字段。--page- 集合的当前页。--per_page- 结果集中返回的最大项目数。默认为 100 个项目。--search- 将结果限制为与某个字符串匹配的项目。--after- 将响应限制为在给定符合 ISO8601 标准的日期之后发布的资源。--before- 将响应限制为在给定符合 ISO8601 标准的日期之前发布的资源。--exclude- 确保结果集排除特定的 ID。--include- 将结果集限制为特定的 ID。--offset- 通过指定数量的项目来偏移结果集。--order- 按照升序或降序对排序属性进行排序。--orderby- 按照对象的属性对集合进行排序。--parent- 将结果集限制为特定父级 ID 的项目。--parent_exclude- 将结果集限制为所有项目,但排除特定父级 ID 的项目。--slug- 将结果集限制为具有特定别名的产品。--status- 将结果集限制为具有特定状态的产品。--type- 将结果集限制为具有特定类型的产品。--sku- 将结果集限制为具有特定 SKU 的产品。--featured- 将结果集限制为精选产品。--category- 将结果集限制为具有特定分类 ID 的产品。--tag- 将结果集限制为具有特定标签 ID 的产品。--shipping_class- 将结果集限制为具有特定配送类型 ID 的产品。--attribute- 将结果集限制为具有特定属性的产品。--attribute_term- 将结果集限制为具有特定属性项 ID 的产品(需要已分配的属性)。--tax_class- 将结果集限制为具有特定税类的产品。--in_stock- 将结果集限制为库存中的产品或缺货的产品。--on_sale- 将结果集限制为正在促销的产品。--min_price- 根据最小价格限制结果集。--max_price- 根据最大价格限制结果集。--fields- 将响应限制为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product create
--name- 产品名称。--slug- 产品别名。--type- 产品类型。--status- 产品状态(帖子状态)。--featured- 是否为推荐产品。--catalog_visibility- 目录可见性。--description- 产品描述。--short_description- 产品简短描述。--sku- 唯一标识符。--regular_price- 产品常规价格。--sale_price- 产品促销价格。--date_on_sale_from- 促销价格的起始日期,使用站点时区。--date_on_sale_from_gmt- 促销价格的起始日期,使用 GMT 时区。--date_on_sale_to- 促销价格的结束日期,使用站点时区。--date_on_sale_to_gmt- 促销价格的结束日期,使用站点时区。--virtual- 如果产品是虚拟产品。--downloadable- 如果产品可以下载。--downloads- 可下载文件的列表。--download_limit- 购买后,可下载文件可以下载的次数。--download_expiry- 可下载文件过期前的天数。--external_url- 产品的外部 URL。仅适用于外部产品。--button_text- 产品的外部按钮文本。仅适用于外部产品。--tax_status- 税收状态。--tax_class- 税类。--manage_stock- 产品级别的库存管理。--stock_quantity- 库存数量。--in_stock- 控制产品在前台显示为“有库存”或“缺货”。--backorders- 如果管理库存,则控制是否允许延期交货。--sold_individually- 允许在单个订单中购买一件商品。--weight- 产品重量(磅)。--dimensions- 产品尺寸。--shipping_class- 配送类型别名。--reviews_allowed- 允许评论。--upsell_ids- 追加销售产品的 ID 列表。--cross_sell_ids- 交叉销售产品的 ID 列表。--parent_id- 产品父级 ID。--purchase_note- 购买后发送给客户的可选备注。--categories- 分类的列表。--tags- 标签的列表。--images- 图像的列表。--attributes- 属性的列表。--default_attributes- 默认变体属性。--menu_order- 菜单排序,用于自定义产品排序。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc product get [id]
--id- 资源的唯一标识符。--context- 发起请求的作用域;确定响应中包含的字段。--fields- 限制响应为特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product update [id]
--id- 资源的唯一标识符。--name- 产品名称。--slug- 产品别名。--type- 产品类型。--status- 产品状态(帖子状态)。--featured- 推荐产品。--catalog_visibility- 目录可见性。--description- 产品描述。--short_description- 产品简短描述。--sku- 唯一标识符。--regular_price- 产品常规价格。--sale_price- 产品促销价格。--date_on_sale_from- 促销价格的起始日期,使用站点时区。--date_on_sale_from_gmt- 促销价格的起始日期,使用 GMT 时区。--date_on_sale_to- 促销价格的结束日期,使用站点时区。--date_on_sale_to_gmt- 促销价格的结束日期,使用站点时区。--virtual- 如果产品是虚拟产品。--downloadable- 如果产品可以下载。--downloads- 可下载文件的列表。--download_limit- 购买后,可下载文件可以下载的次数。--download_expiry- 可下载文件到期前的天数。--external_url- 产品的外部 URL。仅适用于外部产品。--button_text- 产品的外部按钮文本。仅适用于外部产品。--tax_status- 税收状态。--tax_class- 税类。--manage_stock- 产品级别的库存管理。--stock_quantity- 库存数量。--in_stock- 控制产品在前台显示为“有库存”或“缺货”。--backorders- 如果管理库存,则控制是否允许延期交货。--sold_individually- 允许在单个订单中购买一件商品。--weight- 产品重量(磅)。--dimensions- 产品尺寸。--shipping_class- 配送类型别名。--reviews_allowed- 允许评论。--upsell_ids- 追加销售产品的 ID 列表。--cross_sell_ids- 交叉销售产品的 ID 列表。--parent_id- 产品父级 ID。--purchase_note- 购买后发送给客户的可选备注。--categories- 分类列表。--tags- 标签列表。--images- 图片列表。--attributes- 属性列表。--default_attributes- 默认变体属性。--menu_order- 菜单排序,用于自定义产品排序。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc product delete [id]
--id- 资源的唯一标识符。--force- 是否绕过回收站,强制删除。--porcelain- 操作成功时,仅输出 ID。
wc product_attribute_term
wc product_attribute_term list <attribute_id>
--attribute_id- 属性的唯一标识符。--context- 请求的范围;决定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的项数。默认为 100 项。--search- 限制结果,仅包含匹配的字符串。--exclude- 确保结果集中排除指定的 ID。--include- 限制结果集,仅包含指定的 ID。--order- 升序或降序排序。--orderby- 根据资源属性对集合进行排序。--hide_empty- 是否隐藏未分配给任何产品的资源。--parent- 限制结果集,仅包含分配给特定父级的资源。--product- 限制结果集,仅包含分配给特定产品的资源。--slug- 限制结果集,仅包含具有特定别名的资源。--fields- 限制响应,仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_attribute_term create <attribute_id>
--attribute_id- 属性的唯一标识符。--name- 资源的名称。(必需)--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--menu_order- 菜单排序,用于自定义排序资源。--porcelain- 当操作成功时,仅输出 ID。
wc product_attribute_term get <attribute_id> [id]
--id- 资源的唯一标识符。--attribute_id- 属性的唯一标识符。--context- 请求的范围;决定响应中包含的字段。--fields- 限制响应,仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_attribute_term update <attribute_id> [id]
--id- 资源的唯一标识符。--attribute_id- 属性的唯一标识符。--name- 术语名称。--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--menu_order- 菜单排序,用于自定义排序资源。--porcelain- 当操作成功时,仅输出 ID。
wc product_attribute_term delete <attribute_id> [id]
--id- 资源的唯一标识符。--attribute_id- 属性的唯一标识符。--force- 必须设置为 true,因为资源不支持放入回收站。--porcelain- 当操作成功时,仅输出 ID。
wc product_attribute
wc product_attribute list
--context- 发送请求的上下文范围;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_attribute create
--name- 资源的名称。(必需)--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--type- 属性的类型。--order_by- 默认排序顺序。--has_archives- 启用/禁用属性归档。--porcelain- 当操作成功时,仅输出 ID。
wc product_attribute get [id]
--id- 资源的唯一标识符。--context- 发送请求的上下文范围;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_attribute update [id]
--id- 资源的唯一标识符。--name- 属性名称。--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--type- 属性的类型。--order_by- 默认排序顺序。--has_archives- 启用/禁用属性归档。--porcelain- 当操作成功时,仅输出 ID。
wc product_attribute delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为资源不支持放入回收站。--porcelain- 当操作成功时,仅输出 ID。
wc product_cat
wc product_cat list
--context- 发送请求的上下文范围;决定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的项数。默认为 100 项。--search- 限制结果,仅包含匹配的字符串。--exclude- 确保结果集中排除指定的 ID。--include- 限制结果集,仅包含指定的 ID。--order- 按照属性升序或降序排序。--orderby- 按照资源属性排序集合。--hide_empty- 是否隐藏未分配给任何产品的资源。--parent- 限制结果集,仅包含分配给特定父级的资源。--product- 限制结果集,仅包含分配给特定产品的资源。--slug- 限制结果集,仅包含具有特定别名的资源。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_cat create
--name- 资源的名称。(必需)--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--parent- 资源的父级 ID。--description- 资源的 HTML 描述。--display- 分类归档显示类型。--image- 图像数据。--menu_order- 菜单排序,用于自定义资源排序。--porcelain- 当操作成功时,仅输出 ID。
wc product_cat get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;确定响应中包含的字段。--fields- 限制响应为特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_cat update [id]
--id- 资源的唯一标识符。--name- 分类名称。--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--parent- 资源的父级 ID。--description- 资源的 HTML 描述。--display- 分类归档显示类型。--image- 图像数据。--menu_order- 菜单排序,用于自定义资源排序。--porcelain- 当操作成功时,仅输出 ID。
wc product_cat delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为资源不支持放入回收站。--porcelain- 当操作成功时,仅输出 ID。
wc product_review
wc product_review list <product_id>
--product_id- 可变产品的唯一标识符。--id- 变体的唯一标识符。--context- 发送请求的范围;确定响应中包含的字段。--fields- 限制响应为特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_review create <product_id>
--product_id- 可变产品的唯一标识符。--id- 变体的唯一标识符。--review- 评论内容。(必需)--date_created- 评论创建的日期,使用站点的时区。--date_created_gmt- 评论创建的日期,以 GMT 为准。--rating- 评论评分(0 到 5)。--name- 评论者姓名。(必需)--email- 评论者邮箱。(必需)--porcelain- 当操作成功时,仅输出 ID。
wc product_review get <product_id> [id]
--product_id- 可变产品的唯一标识符。--id- 资源的唯一标识符。--context- 发送请求的范围;确定响应中包含的字段。--fields- 限制响应仅包含特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认值: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_review update <product_id> [id]
--product_id- 可变产品的唯一标识符。--id- 资源的唯一标识符。--review- 评论内容。--date_created- 评论创建日期,使用站点时区。--date_created_gmt- 评论创建日期,以 GMT 时区表示。--rating- 评论评分(0 到 5)。--name- 评论者姓名。--email- 评论者邮箱。--porcelain- 操作成功时,仅输出 ID。
wc product_review delete <product_id> [id]
--product_id- 可变产品的唯一标识符。--id- 资源的唯一标识符。--force- 是否绕过回收站,强制删除。--porcelain- 操作成功时,仅输出 ID。
wc product_shipping_class
wc product_shipping_class list
--context- 发送请求的范围;确定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的项数。默认为 100 项。--search- 限制结果,仅包含匹配的字符串。--exclude- 确保结果集中排除指定的 ID。--include- 限制结果集,仅包含指定的 ID。--offset- 通过指定数量的项来偏移结果集。--order- 升序或降序排列排序属性。--orderby- 按资源属性对集合进行排序。--hide_empty- 是否隐藏未分配给任何产品的资源。--product- 限制结果集,仅包含分配给特定产品的资源。--slug- 限制结果集,仅包含具有特定别名的资源。--fields- 限制响应仅包含特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认值: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_shipping_class create
--name- 资源的名称。(必需)--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--porcelain- 操作成功时,仅输出 ID。
wc product_shipping_class get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应仅包含特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_shipping_class update [id]
--id- 资源的唯一标识符。--name- 配送类型的名称。--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--porcelain- 当操作成功时,仅输出 ID。
wc product_shipping_class delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为该资源不支持放入回收站。--porcelain- 当操作成功时,仅输出 ID。
wc product_tag
wc product_tag list
--context- 发送请求的范围;决定响应中包含的字段。--page- 集合的当前页。--per_page- 结果集中返回的最大项目数。默认为 100 个项目。--search- 限制结果,仅包含与字符串匹配的结果。--exclude- 确保结果集排除指定的 ID。--include- 限制结果集仅包含指定的 ID。--offset- 通过指定的项目数偏移结果集。--order- 升序或降序排序属性。--orderby- 按资源属性对集合进行排序。--hide_empty- 是否隐藏未分配给任何产品的资源。--product- 限制结果集仅包含分配给特定产品的资源。--slug- 限制结果集仅包含具有特定别名的资源。--fields- 限制响应仅包含特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_tag create
--name- 资源的名称。(必需)--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--porcelain- 当操作成功时,仅输出 ID。
wc product_tag get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;决定响应中包含的字段。--fields- 限制响应仅包含特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_tag update [id]
--id- 资源的唯一标识符。--name- 标签名。--slug- 资源的字母数字标识符,该标识符在资源类型中是唯一的。--description- 资源的 HTML 描述。--porcelain- 操作成功时,仅输出 ID。
wc product_tag delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为该资源不支持移至回收站。--porcelain- 操作成功时,仅输出 ID。
wc product_variation
wc product_variation list <product_id>
--product_id- 可变产品的唯一标识符。--context- 发起请求的范围;确定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多的项目数。默认为 100 个项目。--search- 将结果限制为与字符串匹配的项目。--after- 将响应限制为在给定 ISO8601 兼容日期之后发布的资源。--before- 将响应限制为在给定 ISO8601 兼容日期之前发布的资源。--exclude- 确保结果集排除特定的 ID。--include- 将结果集限制为特定的 ID。--offset- 通过指定的项目数偏移结果集。--order- 按照升序或降序排序属性。--orderby- 按照对象的属性进行排序。--parent- 将结果集限制为特定父 ID 的资源。--parent_exclude- 将结果集限制为所有项目,但排除特定父 ID 的项目。--slug- 将结果集限制为具有特定别名的产品。--status- 将结果集限制为具有特定状态的产品。--type- 将结果集限制为具有特定类型的产品。--sku- 将结果集限制为具有特定 SKU 的产品。--featured- 将结果集限制为精选产品。--category- 将结果集限制为分配了特定分类 ID 的产品。--tag- 将结果集限制为分配了特定标签 ID 的产品。--shipping_class- 将结果集限制为分配了特定配送类型的产品。--attribute- 将结果集限制为具有特定属性的产品。--attribute_term- 将结果集限制为具有特定属性项 ID 的产品(需要已分配的属性)。--tax_class- 将结果集限制为具有特定税类的产品。--in_stock- 将结果集限制为在库存或缺货的产品。--on_sale- 将结果集限制为正在促销的产品。--min_price- 根据最低价格限制结果集。--max_price- 根据最高价格限制结果集。--fields- 限制响应为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc product_variation create "<product_id>"
--product_id- 可变产品的唯一标识符。--description- 变体的描述。--sku- 唯一标识符。--regular_price- 变体的常规价格。--sale_price- 变体的促销价格。--date_on_sale_from- 促销价格的起始日期,使用网站的时区。--date_on_sale_from_gmt- 促销价格的起始日期,使用 GMT 时区。--date_on_sale_to- 促销价格的结束日期,使用网站的时区。--date_on_sale_to_gmt- 促销价格的结束日期,使用 GMT 时区。--visible- 定义该属性是否在产品的“其他信息”选项卡中可见。--virtual- 如果该变体是虚拟的。--downloadable- 如果该变体可以下载。--downloads- 可下载文件的列表。--download_limit- 购买后,可下载文件可以下载的次数。--download_expiry- 访问可下载文件的天数限制。--tax_status- 税收状态。--tax_class- 税类。--manage_stock- 在变体级别进行库存管理。--stock_quantity- 库存数量。--in_stock- 控制该变体是否在前端显示为“有库存”或“缺货”。--backorders- 如果管理库存,则控制是否允许延期交货。--weight- 变体的重量(磅)。--dimensions- 变体的尺寸。--shipping_class- 配送类型的别名。--image- 变体的图像数据。--attributes- 属性列表。--menu_order- 菜单排序,用于自定义产品排序。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc product_variation get "<product_id>" [id]
--product_id- 可变产品的唯一标识符。--id- 变体的唯一标识符。--context- 发起请求的作用域;确定响应中包含的字段。--fields- 限制响应仅包含特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认值: table
选项: table, json, csv, ids, yaml, count, headers, body, envelope
wc product_variation update <product_id> [id]
--product_id- 可变产品的唯一标识符。--id- 变体的唯一标识符。--description- 变体描述。--sku- 唯一标识符。--regular_price- 变体的常规价格。--sale_price- 变体的促销价格。--date_on_sale_from- 促销价格的起始日期,使用站点时区。--date_on_sale_from_gmt- 促销价格的起始日期,使用 GMT 时区。--date_on_sale_to- 促销价格的结束日期,使用站点时区。--date_on_sale_to_gmt- 促销价格的结束日期,使用 GMT 时区。--visible- 定义该属性是否在产品的“其他信息”选项卡中可见。--virtual- 如果该变体是虚拟的。--downloadable- 如果该变体可以下载。--downloads- 可下载文件的列表。--download_limit- 购买后,可下载文件可以下载的次数。--download_expiry- 可下载文件过期前的天数。--tax_status- 税收状态。--tax_class- 税类。--manage_stock- 在变体级别进行库存管理。--stock_quantity- 库存数量。--in_stock- 控制该变体在前台显示为“有库存”或“缺货”。--backorders- 如果管理库存,则控制是否允许延期交货。--weight- 变体的重量(磅)。--dimensions- 变体的尺寸。--shipping_class- 配送类型的别名。--image- 变体的图像数据。--attributes- 属性列表。--menu_order- 菜单排序,用于自定义产品排序。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc product_variation delete <product_id> [id]
--product_id- 可变产品的唯一标识符。--id- 变体的唯一标识符。--force- 是否绕过回收站,强制删除。--porcelain- 操作成功时,仅输出 ID。
wc setting
wc setting get [id]
--group- 设置组 ID。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项: table, json, csv, ids, yaml, count, headers, body, envelope
wc setting update [id]
--group- 设置组 ID。--id- 资源的唯一标识符。--value- 设置值。--porcelain- 操作成功时,仅输出 ID。
wc shipping_method
wc shipping_method list
--context- 请求的上下文;决定响应中包含的字段。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_method get [id]
--id- 资源的唯一标识符。--context- 请求的上下文;决定响应中包含的字段。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone
wc shipping_zone list
--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone create
--name- 配送区域名称。(必需)--order- 配送区域顺序。--porcelain- 当操作成功时,仅输出 ID。
wc shipping_zone get [id]
--id- 资源的唯一 ID。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone update [id]
--id- 资源的唯一 ID。--name- 配送区域名称。--order- 配送区域顺序。--porcelain- 当操作成功时,仅输出 ID。
wc shipping_zone delete [id]
--id- 资源的唯一 ID。--force- 是否绕过回收站,强制删除。--porcelain- 当操作成功时,仅输出 ID。
wc shipping_zone_location
wc shipping_zone_location list
--id- 资源的唯一 ID。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone_method
wc shipping_zone_method list
--zone_id- 区域的唯一 ID。--fields- 限制响应的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone_method create
--zone_id- 区域的唯一 ID。--order- 配送方式的排序顺序。--enabled- 配送方式的启用状态。--settings- 配送方式的设置。--method_id- 配送方式 ID。 (必需)--porcelain- 当操作成功时,仅输出 ID。
wc shipping_zone_method get [id]
--zone_id- 区域的唯一 ID。--instance_id- 实例的唯一 ID。--fields- 限制响应仅包含特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shipping_zone_method update [id]
--zone_id- 区域的唯一 ID。--instance_id- 实例的唯一 ID。--order- 配送方式的排序顺序。--enabled- 配送方式的启用状态。--settings- 配送方式的设置。--porcelain- 当操作成功时,仅输出 ID。
wc shipping_zone_method delete [id]
--zone_id- 区域的唯一 ID。--instance_id- 实例的唯一 ID。--force- 是否绕过回收站,强制删除。--porcelain- 当操作成功时,仅输出 ID。
wc shop_coupon
wc shop_coupon list
--context- 请求的作用域;决定响应中包含的字段。--page- 集合的当前页。--per_page- 结果集中返回的最大项目数。默认为 100 个项目。--search- 限制结果以匹配某个字符串。--after- 限制响应仅包含在给定 ISO8601 兼容日期之后发布的资源。--before- 限制响应仅包含在给定 ISO8601 兼容日期之前发布的资源。--exclude- 确保结果集排除特定的 ID。--include- 限制结果集仅包含特定的 ID。--offset- 通过指定数量的项目偏移结果集。--order- 按照属性升序或降序排序。--orderby- 按照对象属性对集合进行排序。--code- 限制结果集仅包含具有特定代码的资源。--fields- 限制响应仅包含特定字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_coupon create
--code- 优惠券代码。(必填)--amount- 折扣金额。 始终应为数字,即使是设置百分比。--discount_type- 确定要应用的折扣类型。--description- 优惠券描述。--date_expires- 优惠券到期日期,使用网站的时区。--date_expires_gmt- 优惠券到期日期,以 GMT 为准。--individual_use- 如果为 true,则优惠券只能单独使用。 其他已应用的优惠券将从购物车中移除。--product_ids- 优惠券可使用的产品 ID 列表。--excluded_product_ids- 优惠券不可使用的产品 ID 列表。--usage_limit- 优惠券总共可以使用多少次。--usage_limit_per_user- 每个客户可以使用优惠券的次数。--limit_usage_to_x_items- 优惠券可以应用的购物车中商品的最大数量。--free_shipping- 如果为 true,并且如果免费配送方法需要优惠券,则此优惠券将启用免费配送。--product_categories- 优惠券适用的分类 ID 列表。--excluded_product_categories- 优惠券不适用的分类 ID 列表。--exclude_sale_items- 如果为 true,则此优惠券将不应用于具有促销价格的商品。--minimum_amount- 优惠券生效前,购物车中所需的最小订单金额。--maximum_amount- 使用优惠券时允许的最大订单金额。--email_restrictions- 可以使用此优惠券的 Email 地址列表。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc shop_coupon get [id]
--id- 资源的唯一标识符。--context- 发送请求的范围;确定响应中包含的字段。--fields- 限制响应仅包含特定字段。 默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认: table
选项: table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_coupon update [id]
--id- 资源的唯一标识符。--code- 优惠券代码。--amount- 折扣金额。 始终应为数字,即使是设置百分比。--discount_type- 确定要应用的折扣类型。--description- 优惠券描述。--date_expires- 优惠券到期日期,采用网站的时区。--date_expires_gmt- 优惠券到期日期,采用 GMT 时区。--individual_use- 如果为 true,则优惠券只能单独使用。 其他已应用的优惠券将从购物车中移除。--product_ids- 优惠券可使用的产品 ID 列表。--excluded_product_ids- 优惠券不可使用的产品 ID 列表。--usage_limit- 优惠券总共可以使用多少次。--usage_limit_per_user- 优惠券每个客户可以使用多少次。--limit_usage_to_x_items- 优惠券可以应用的购物车中商品的最大数量。--free_shipping- 如果为 true,并且如果免费配送方法需要优惠券,则此优惠券将启用免费配送。--product_categories- 优惠券适用的分类 ID 列表。--excluded_product_categories- 优惠券不适用的分类 ID 列表。--exclude_sale_items- 如果为 true,则此优惠券将不应用于具有促销价格的商品。--minimum_amount- 优惠券生效前,购物车中所需的最小订单金额。--maximum_amount- 使用优惠券时允许的最大订单金额。--email_restrictions- 可以使用此优惠券的 Email 地址列表。--meta_data- 元数据。--porcelain- 操作成功时,仅输出 ID。
wc shop_coupon delete [id]
--id- 资源的唯一标识符。--force- 是否绕过回收站,强制删除。--porcelain- 操作成功时,仅输出 ID。
wc shop_order
wc shop_order list
--context- 请求的范围;决定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多包含的项目数。默认为 100 个项目。--search- 限制结果,仅包含匹配的字符串。--after- 限制响应,仅包含在给定符合 ISO8601 标准的日期之后发布的资源。--before- 限制响应,仅包含在给定符合 ISO8601 标准的日期之前发布的资源。--exclude- 确保结果集中排除特定的 ID。--include- 限制结果集,仅包含特定的 ID。--offset- 通过指定数量的项目来偏移结果集。--order- 按照升序或降序对排序属性进行排序。--orderby- 按照对象的属性对集合进行排序。--parent- 限制结果集,仅包含特定父 ID 的项目。--parent_exclude- 限制结果集,包含所有项目,但排除特定父 ID 的项目。--status- 限制结果集,仅包含分配了特定状态的订单。--customer- 限制结果集,仅包含分配给特定客户的订单。--product- 限制结果集,仅包含分配给特定产品的订单。--dp- 每个资源中使用的十进制位数。--fields- 限制响应,仅包含特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认值: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_order create
--parent_id- 父订单 ID。--status- 订单状态。--currency- 订单创建时使用的货币,以 ISO 格式表示。--customer_id- 拥有该订单的用户 ID。访客为 0。--customer_note- 客户在结账时留下的备注。--billing- 账单地址。--shipping- 配送地址。--payment_method- 支付方式 ID。--payment_method_title- 支付方式标题。--transaction_id- 唯一的交易 ID。--meta_data- 元数据。--line_items- 商品明细数据。--shipping_lines- 配送明细数据。--fee_lines- 费用明细数据。--coupon_lines- 优惠券明细数据。--set_paid- 定义订单是否已支付。如果设置为 true,则会将状态设置为“处理中”,并减少库存数量。--porcelain- 当操作成功时,仅输出 ID。
wc shop_order get [id]
--id- 资源的唯一标识符。--context- 请求的范围;决定响应中包含的字段。--fields- 限制响应,仅包含特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认值: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_order update [id]
--id- 资源的唯一标识符。--parent_id- 父订单 ID。--status- 订单状态。--currency- 订单创建时使用的货币,采用 ISO 格式。--customer_id- 拥有该订单的用户 ID。访客用户为 0。--customer_note- 客户在结账时留下的备注。--billing- 账单地址。--shipping- 收货地址。--payment_method- 支付方式 ID。--payment_method_title- 支付方式标题。--transaction_id- 唯一的交易 ID。--meta_data- 元数据。--line_items- 商品明细数据。--shipping_lines- 运费明细数据。--fee_lines- 费用明细数据。--coupon_lines- 优惠券明细数据。--set_paid- 定义订单是否已支付。如果设置为 true,将更改状态为“处理中”,并减少库存商品数量。--porcelain- 操作成功时,仅输出 ID。
wc shop_order delete [id]
--id- 资源的唯一标识符。--force- 是否绕过回收站,强制删除。--porcelain- 操作成功时,仅输出 ID。
wc shop_order_refund
wc shop_order_refund list <order_id>
--order_id- 订单 ID。--context- 请求的作用域;确定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的条目数。默认为 100 个条目。--search- 将结果限制为与字符串匹配的条目。--after- 将响应限制为在给定 ISO8601 兼容日期之后发布的资源。--before- 将响应限制为在给定 ISO8601 兼容日期之前发布的资源。--exclude- 确保结果集排除特定的 ID。--include- 将结果集限制为特定的 ID。--offset- 通过指定的数量偏移结果集。--order- 排序属性的升序或降序。--orderby- 按对象属性对集合进行排序。--parent- 将结果集限制为特定父 ID 的条目。--parent_exclude- 将结果集限制为所有项目,但排除特定父 ID 的项目。--dp- 在每个资源中使用的十进制位数。--fields- 将响应限制为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_order_refund create <order_id>
--order_id- 订单 ID。--amount- 退款金额。--reason- 退款原因。--refunded_by- 创建退款的用户 ID。--meta_data- 元数据。--line_items- 商品明细数据。--api_refund- 如果设置为 true,则使用支付网关 API 生成退款。--porcelain- 操作成功时,仅输出 ID。
wc shop_order_refund get <order_id> [id]
--order_id- 订单 ID。--id- 资源的唯一标识符。--context- 发送请求的上下文;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc shop_order_refund delete <order_id> [id]
--order_id- 订单 ID。--id- 资源的唯一标识符。--force- 必须设置为 true,因为该资源不支持放入回收站。--porcelain- 操作成功时,仅输出 ID。
wc tax
wc tax list
--context- 发送请求的上下文;决定响应中包含的字段。--page- 集合的当前页。--per_page- 结果集中返回的最大项目数。默认为 100 个项目。--search- 限制结果以匹配字符串。--exclude- 确保结果集排除指定的 ID。--include- 限制结果集为指定的 ID。--offset- 通过指定的项目数偏移结果集。--order- 按照属性升序或降序排序。--orderby- 按照对象属性排序集合。--class- 按照税类排序。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc tax create
--country- 国家 ISO 3166 代码。--state- 州代码。--postcode- 邮政编码 / ZIP 码。--city- 城市名称。--rate- 税率。--name- 税率名称。--priority- 税优先级。--compound- 是否为复合税率。--shipping- 是否也应用于配送。--order- 指示查询中出现的顺序。--class- 税类。--porcelain- 操作成功时,仅输出 ID。
wc tax get [id]
--id- 资源的唯一标识符。--context- 发送请求的上下文;决定响应中包含的字段。--fields- 限制响应仅包含指定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定格式呈现响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc tax update [id]
--id- 资源的唯一标识符。--country- 国家 ISO 3166 代码。--state- 州代码。--postcode- 邮政编码 / 邮编。--city- 城市名称。--rate- 税率。--name- 税率名称。--priority- 税优先级。--compound- 是否为复合税率。--shipping- 是否也应用于配送。--order- 在查询中显示的顺序。--class- 税类。--porcelain- 操作成功时,仅输出 ID。
wc tax delete [id]
--id- 资源的唯一标识符。--force- 必须为 true,因为该资源不支持放入回收站。--porcelain- 操作成功时,仅输出 ID。
wc tax_class
wc tax_class list
--context- 请求的范围;决定响应中包含的字段。--fields- 限制响应为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc tax_class create
--name- 税类名称。(必需)--porcelain- 操作成功时,仅输出 ID。
wc tax_class delete [id]
--slug- 资源的唯一别名。--force- 必须为 true,因为该资源不支持放入回收站。--porcelain- 操作成功时,仅输出 ID。
wc webhook
wc webhook list
--context- 请求的范围;决定响应中包含的字段。--page- 集合的当前页。--per_page- 返回结果集中最多显示的条目数。默认为 100 个条目。--search- 限制结果,仅包含匹配的字符串。--after- 限制响应,仅包含已发布的资源,发布时间晚于指定的 ISO8601 格式日期。--before- 限制响应,仅包含已发布的资源,发布时间早于指定的 ISO8601 格式日期。--exclude- 确保结果集排除特定的 ID。--include- 限制结果集为特定的 ID。--offset- 通过指定的数量的条目偏移结果集。--order- 按照升序或降序排列。--orderby- 按照对象的属性进行排序。--status- 限制结果集,仅包含具有特定状态的 webhook。--fields- 限制响应为特定的字段。默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认: table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc webhook create
--name- Webhook 的友好名称。--status- Webhook 的状态。--topic- Webhook 的主题。 (必需)--secret- Webhook 的密钥。 (必需)--delivery_url- Webhook 的推送 URL。 (必需)--porcelain- 当操作成功时,只输出 ID。
wc webhook get [id]
--id- 资源的唯一标识符。--context- 发送请求的上下文;决定响应中包含的字段。--fields- 限制响应的字段。 默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc webhook update [id]
--id- 资源的唯一标识符。--name- Webhook 的友好名称。--status- Webhook 的状态。--topic- Webhook 的主题。--secret- 用于生成推送 webhook 的哈希值的密钥,并在请求头中提供。 如果未提供,则默认为当前用户的 ID|用户名 的 MD5 哈希值。--porcelain- 当操作成功时,只输出 ID。
wc webhook delete [id]
--id- 资源的唯一标识符。--force- 必须设置为 true,因为资源不支持放入回收站。--porcelain- 当操作成功时,只输出 ID。
wc webhook_delivery
wc webhook_delivery list
--webhook_id- Webhook 的唯一标识符。--context- 发送请求的上下文;决定响应中包含的字段。--fields- 限制响应的字段。 默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
wc webhook_delivery get [id]
--webhook_id- Webhook 的唯一标识符。--id- 资源的唯一标识符。--context- 发送请求的上下文;决定响应中包含的字段。--fields- 限制响应的字段。 默认为所有字段。--field- 获取单个字段的值。--format- 以特定的格式渲染响应。
默认:table
选项:table, json, csv, ids, yaml, count, headers, body, envelope
WooCommerce CLI 示例
每个 Command 的完整 Documentation 可以使用 --help 参数查看。 以下是一些示例 Command,以展示 CLI 的功能。
以下所有示例都使用用户 ID 1(通常是 Admin 账户),但您应该将其替换为您的用户账户。
您还可以通过查看 我们 CLI 测试的测试文件 找到其他示例(不包含 Output)。
每个 Command 都有一个 .feature 文件。 例如,这些是关于 Payment Gateway 的一些 Command。
清除 Product / 商店的 Transient 缓存
Command:
$ wp wc tool run clear_transients --user=1
Response:
Success: Updated system_status_tool clear_transients.
列表显示所有系统工具
命令:
$ wp wc tool list --user=1
回复:
WooCommerce 工具箱
本工具箱提供了多种实用功能,用于管理和维护您的 WooCommerce 商店。
工具列表
以下是可用的工具列表:
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
| id | name | action | description |
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
| clear_transients | WC 瞬态对象 | 清理瞬态对象 | 此工具将清理产品/商店的瞬态对象缓存。 |
| clear_expired_transients | 过期瞬态对象 | 清理过期瞬态对象 | 此工具将清理 WordPress 中的所有过期瞬态对象。 |
| delete_orphaned_variations | 孤立的变体 | 删除孤立的变体 | 此工具将删除所有没有父对象的变体。 |
| recount_terms | 产品分类计数 | 重新计算产品分类计数 | 此工具将重新计算产品分类计数,当您以隐藏产品于目录的方式更改设置时非常有用。 |
| | | | |
| reset_roles | 权限 | 重置权限 | 此工具会将管理员、客户和商店管理员角色重置为默认值。 如果您的用户无法访问所有 WooCommerce 管理页面,请使用此功能。 |
| | | | |
| clear_sessions | 客户会话 | 清理所有会话 | <strong class="red">注意:</strong> 此工具将删除所有客户会话数据,包括任何当前的购物车内容。 |
| | | | |
| install_pages | 安装 WooCommerce 页面 | 安装页面 | <strong class="red">注意:</strong> 此工具将安装所有缺失的 WooCommerce 页面。 已经定义和设置的页面不会被替换。 |
| | | | |
| delete_taxes | 删除所有 WooCommerce 税率 | 删除所有税率 | <strong class="red">注意:</strong> 此选项将删除所有税率,请谨慎使用。 |
| | | | |
| reset_tracking | 重置使用情况跟踪设置 | 重置使用情况跟踪设置 | 这将重置您的使用情况跟踪设置,导致它再次显示“选择加入”横幅,并且不会发送任何数据。 |
| | | | |
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
工具说明:
clear_transients: 清理 WooCommerce 瞬态对象缓存。clear_expired_transients: 清理 WordPress 中所有过期的瞬态对象。delete_orphaned_variations: 删除没有父对象的变体。recount_terms: 重新计算产品分类计数。reset_roles: 重置管理员、客户和商店管理员角色的权限。clear_sessions: 清理所有客户会话数据。install_pages: 安装所有缺失的 WooCommerce 页面。delete_taxes: 删除所有 WooCommerce 税率。reset_tracking: 重置使用情况跟踪设置。
使用方法:
- 选择您要使用的工具。
- 点击相应的按钮或链接。
- 根据提示完成操作。
注意事项:
- 某些工具可能会删除重要数据,请在使用前仔细阅读说明。
- 在进行任何更改之前,建议备份您的数据库。
常见问题:
- 如何安装 WooCommerce? 请参考 Install WooCommerce 文档。
- 如何管理我的产品? 请访问 WooCommerce 管理页面。
- 如何设置税率? 请在 WooCommerce 设置中配置税率。
- 如何启用使用情况跟踪? 请在 WooCommerce 设置中启用使用情况跟踪。
- 如何访问我的 WooCommerce 数据库? 您可以使用数据库管理工具访问您的数据库。
- 如何修改 WooCommerce 的设置? 您可以在 WooCommerce 设置页面修改各种选项。
- 如何删除 WooCommerce 页面? 您可以使用 WordPress 的页面管理功能删除页面。
- 如何解决 WooCommerce 访问权限问题? 请检查用户的角色和权限设置。
- 如何清除 WooCommerce 缓存? 您可以使用缓存插件或手动清除缓存。
- 如何恢复 WooCommerce 数据库? 您可以使用备份文件恢复数据库。
更多信息:
术语表:
- 瞬态 (Transient): 临时数据。
- 数据库 (Database): 存储数据的系统。
- 设置 (Settings): 配置选项。
- 安装 (Install): 将软件或插件添加到系统中。
- 角色 (Role): 用户权限级别。
- 网页 (Page): 网站页面。
- 安装 WooCommerce (Install WooCommerce): 将 WooCommerce 插件安装到 WordPress 网站。
- 使用情况跟踪 (Usage Tracking): 收集用户行为数据。
- 所有页面 (All Pages): 网站的所有页面。
- 税率 (Tax Rate): 增值税或其他税费的百分比。
- 跟踪 (Tracking): 监控和记录数据。
- 会话 (Session): 用户与网站的交互过程。
- 替换 (Replace): 用新的内容代替旧的内容。
- 当前 (Current): 当前状态或值。
- 产品 (Product): 商店中销售的商品或服务。
- 删除 (Delete): 移除或清除。
- 管理 (Manage): 组织和控制。
- 选项 (Option): 可选的配置或设置。
- 访问 (Access): 访问权限。
- 缓存 (Cache): 临时存储数据以提高性能。
创建客户
命令:
$ wp wc customer create --email='woo@woo.local' --user=1 --billing='{"first_name":"Bob","last_name":"Tester","company":"Woo", "address_1": "123 Main St.", "city":"New York", "state:": "NY", "country":"USA"}' --shipping='{"first_name":"Bob","last_name":"Tester","company":"Woo", "address_1": "123 Main St.", "city":"New York", "state:": "NY", "country":"USA"}' --password='hunter2' --username='mrbob' --first_name='Bob' --last_name='Tester'
响应:
Success: Created customer 17.
以 CSV 格式获取客户
命令:
$ wp wc customer get 17 --user=1 --format=csv
响应:
Field,Value
id,17
date_created,2016-12-09T20:22:10
date_modified,2016-12-09T20:22:10
email,woo@woo.local
first_name,Bob
last_name,Tester
role,客户
username,mrbob
billing,"{""first_name"":""Bob"",""last_name"":""Tester"",""company"":""Woo"",""address_1"":""123 Main St."",""address_2"":"""",""city"":""New York"",""state"":"""",""postcode"":"""",
""country"":""USA"",""email"":"""",""phone"":""""}"
shipping,"{""first_name"":""Bob"",""last_name"":""Tester"",""company"":""Woo"",""address_1"":""123 Main St."",""address_2"":"""",""city"":""New York"",""state"":"""",""postcode"":"""",
""country"":""USA""}"
is_paying_customer,false
meta_data,"[{""id"":825,""key"":""shipping_company"",""value"":""Woo""},{""id"":829,""key"":""_order_count"",""value"":""0""},{""id"":830,""key"":""_money_spent"",""value"":""0""}]"
orders_count,0
total_spent,0.00
avatar_url,http://2.gravatar.com/avatar/5791d33f7d6472478c0b5fa69133f09a?s=96
在订单 355 上添加客户备注
命令:
$ wp wc order_note create 355 --note="Great repeat customer" --customer_note=true --user=1
响应:
Success: Created order_note 286.
获取订单备注
命令:
$ wp wc order_note get 355 286 --user=1
响应:
+---------------+-----------------------+
| Field | Value |
+---------------+-----------------------+
| id | 286 |
| date_created | 2016-12-09T20:27:26 |
| note | Great repeat customer |
| customer_note | true |
+---------------+-----------------------+
更新优惠券
命令:
$ wp wc shop_coupon update 45 --amount='10' --discount_type='percent' --free_shipping=true --user=1
响应:
Success: Updated shop_coupon 45.
获取优惠券
命令:
$ wp wc shop_coupon get 45 --user=1
响应:
+-----------------------------+---------------------+
| 字段 | 值 |
+-----------------------------+---------------------+
| id | 45 |
| code | hello |
| amount | 10.00 |
| date_created | 2016-08-09T17:37:28 |
| date_modified | 2016-12-09T20:30:32 |
| discount_type | percent |
| description | Yay |
| date_expires | 2016-10-22T00:00:00 |
| usage_count | 2 |
| individual_use | false |
| product_ids | [] |
| excluded_product_ids | [] |
| usage_limit | null |
| usage_limit_per_user | null |
| limit_usage_to_x_items | null |
| free_shipping | true |
| product_categories | [] |
| excluded_product_categories | [] |
| exclude_sale_items | false |
| minimum_amount | 0.00 |
| maximum_amount | 0.00 |
| email_restrictions | [] |
| used_by | ["1","1"] |
| meta_data | [] |
+-----------------------------+---------------------+
使用 WP CLI 升级数据库
当 WooCommerce 发布新版本时,通常会提示您运行数据库升级。 虽然可以通过 WP 后台进行此操作,但高级用户可能更喜欢通过 CLI 运行这些升级,例如在繁忙的商店中,以避免可能发生的超时。
要更新数据库,请使用以下 CLI 命令:
$ wp wc update
不需要额外的参数,只会运行待审的升级。 升级完成后,将显示新的版本。
WooCommerce CLI 示例
每个命令的完整文档可通过 --help 获取。以下是一些示例命令,展示 CLI 的功能。
以下所有示例都使用用户 ID 1(通常是管理员账户),但您应将其替换为您自己的用户账户。
您还可以通过查看 CLI 测试的测试文件 来查找其他示例(无输出)。
每个命令都有一个 .feature 文件。例如,这些是一些支付网关命令。
清除产品/购物瞬态缓存
命令:
$ wp wc tool run clear_transients --user=1
响应:
成功:已更新系统状态工具 clear_transients。
列出所有系统工具
命令:
$ wp wc tool list --user=1
响应:
WooCommerce 工具箱
本工具箱提供了多种实用功能,用于管理和维护您的 WooCommerce 商店。
工具列表
以下是可用的工具列表:
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
| id | name | action | description |
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
| clear_transients | WC 瞬态对象 | 清理瞬态对象 | 此工具将清理产品/商店的瞬态对象缓存。 |
| clear_expired_transients | 过期瞬态对象 | 清理过期瞬态对象 | 此工具将清理 WordPress 中的所有过期瞬态对象。 |
| delete_orphaned_variations | 孤立的变体 | 删除孤立的变体 | 此工具将删除所有没有父对象的变体。 |
| recount_terms | 产品分类计数 | 重新计算产品分类计数 | 此工具将重新计算产品分类计数,当您以隐藏产品于目录的方式更改设置时非常有用。 |
| | | | |
| reset_roles | 权限 | 重置权限 | 此工具会将管理员、客户和商店管理员角色重置为默认值。 如果您的用户无法访问所有 WooCommerce 管理页面,请使用此功能。 |
| | | | |
| clear_sessions | 客户会话 | 清理所有会话 | <strong class="red">注意:</strong> 此工具将删除所有客户会话数据,包括任何当前的购物车内容。 |
| | | | |
| install_pages | 安装 WooCommerce 页面 | 安装页面 | <strong class="red">注意:</strong> 此工具将安装所有缺失的 WooCommerce 页面。 已经定义和设置的页面不会被替换。 |
| | | | |
| delete_taxes | 删除所有 WooCommerce 税率 | 删除所有税率 | <strong class="red">注意:</strong> 此选项将删除所有税率,请谨慎使用。 |
| | | | |
| reset_tracking | 重置使用情况跟踪设置 | 重置使用情况跟踪设置 | 这将重置您的使用情况跟踪设置,导致它再次显示“选择加入”横幅,并且不会发送任何数据。 |
| | | | |
+----------------------------+----------------------------------+-------------------------------+-----------------------------------------------------------------------------------+
工具说明:
clear_transients: 清理 WooCommerce 瞬态对象缓存。clear_expired_transients: 清理 WordPress 中所有过期的瞬态对象。delete_orphaned_variations: 删除没有父对象的变体。recount_terms: 重新计算产品分类计数。reset_roles: 重置管理员、客户和商店管理员角色的权限。clear_sessions: 清理所有客户会话数据。install_pages: 安装所有缺失的 WooCommerce 页面。delete_taxes: 删除所有 WooCommerce 税率。reset_tracking: 重置使用情况跟踪设置。
使用方法:
- 选择您要使用的工具。
- 点击相应的按钮或链接。
- 根据提示完成操作。
注意事项:
- 某些工具可能会删除重要数据,请在使用前仔细阅读说明。
- 在进行任何更改之前,建议备份您的数据库。
常见问题:
- 如何安装 WooCommerce? 请参考 Install WooCommerce 文档。
- 如何管理我的产品? 请访问 WooCommerce 管理页面。
- 如何设置税率? 请在 WooCommerce 设置中配置税率。
- 如何启用使用情况跟踪? 请在 WooCommerce 设置中启用使用情况跟踪。
- 如何访问我的 WooCommerce 数据库? 您可以使用数据库管理工具访问您的数据库。
- 如何修改 WooCommerce 的设置? 您可以在 WooCommerce 设置页面修改各种选项。
- 如何删除 WooCommerce 页面? 您可以使用 WordPress 的页面管理功能删除页面。
- 如何解决 WooCommerce 访问权限问题? 请检查用户的角色和权限设置。
- 如何清除 WooCommerce 缓存? 您可以使用缓存插件或手动清除缓存。
- 如何恢复 WooCommerce 数据库? 您可以使用备份文件恢复数据库。
更多信息:
术语表:
- 瞬态 (Transient): 临时数据。
- 数据库 (Database): 存储数据的系统。
- 设置 (Settings): 配置选项。
- 安装 (Install): 将软件或插件添加到系统中。
- 角色 (Role): 用户权限级别。
- 网页 (Page): 网站页面。
- 安装 WooCommerce (Install WooCommerce): 将 WooCommerce 插件安装到 WordPress 网站。
- 使用情况跟踪 (Usage Tracking): 收集用户行为数据。
- 所有页面 (All Pages): 网站的所有页面。
- 税率 (Tax Rate): 增值税或其他税费的百分比。
- 跟踪 (Tracking): 监控和记录数据。
- 会话 (Session): 用户与网站的交互过程。
- 替换 (Replace): 用新的内容代替旧的内容。
- 当前 (Current): 当前状态或值。
- 产品 (Product): 商店中销售的商品或服务。
- 删除 (Delete): 移除或清除。
- 管理 (Manage): 组织和控制。
- 选项 (Option): 可选的配置或设置。
- 访问 (Access): 访问权限。
- 缓存 (Cache): 临时存储数据以提高性能。
创建客户
命令:
$ wp wc customer create --email='woo@woo.local' --user=1 --billing='{"first_name":"Bob","last_name":"Tester","company":"Woo", "address_1": "123 Main St.", "city":"New York", "state:": "NY", "country":"USA"}' --shipping='{"first_name":"Bob","last_name":"Tester","company":"Woo", "address_1": "123 Main St.", "city":"New York", "state:": "NY", "country":"USA"}' --password='hunter2' --username='mrbob' --first_name='Bob' --last_name='Tester'
回复:
成功:已创建客户 17。
以 CSV 格式获取客户信息
命令:
$ wp wc customer get 17 --user=1 --format=csv
响应:
字段,值
id,17
date_created,2016-12-09T20:22:10
date_modified,2016-12-09T20:22:10
email,woo@woo.local
first_name,Bob
last_name,Tester
role,customer
username,mrbob
billing,"{""first_name"":""Bob"",""last_name"":""Tester"",""company"":""Woo"",""address_1"":""123 Main St."",""address_2"":"""",""city"":""New York"",""state"":"""",""postcode"":"""","
"country"":""USA"",""email"":"""",""phone"":""""}"
shipping,"{""first_name"":""Bob"",""last_name"":""Tester"",""company"":""Woo"",""address_1"":""123 Main St."",""address_2"":"""",""city"":""New York"",""state"":"""",""postcode"":"""",
""country"":""USA""}"
is_paying_customer,false
meta_data,"[{""id"":825,""key"":""shipping_company"",""value"":""Woo""},{""id"":829,""key"":""_order_count"",""value"":""0""},{""id"":830,""key"":""_money_spent"",""value"":""0""}]"
orders_count,0
total_spent,0.00
avatar_url,http://2.gravatar.com/avatar/5791d33f7d6472478c0b5fa69133f09a?s=96
在订单 355 上添加客户备注
命令:
$ wp wc order_note create 355 --note="Great repeat customer" --customer_note=true --user=1
回复:
Success: Created order_note 286.
获取订单备注
命令:
$ wp wc order_note get 355 286 --user=1
回复:
+---------------+-----------------------+
| Field | Value |
+---------------+-----------------------+
| id | 286 |
| date_created | 2016-12-09T20:27:26 |
| note | Great repeat customer |
| customer_note | true |
+---------------+-----------------------+
更新优惠券
命令:
$ wp wc shop_coupon update 45 --amount='10' --discount_type='percent' --free_shipping=true --user=1
响应:
Success: Updated shop_coupon 45.
获取优惠券
命令:
$ wp wc shop_coupon get 45 --user=1
响应:
+-----------------------------+---------------------+
| 字段 | 值 |
+-----------------------------+---------------------+
| id | 45 |
| code | hello |
| amount | 10.00 |
| date_created | 2016-08-09T17:37:28 |
| date_modified | 2016-12-09T20:30:32 |
| discount_type | percent |
| description | Yay |
| date_expires | 2016-10-22T00:00:00 |
| usage_count | 2 |
| individual_use | false |
| product_ids | [] |
| excluded_product_ids | [] |
| usage_limit | null |
| usage_limit_per_user | null |
| limit_usage_to_x_items | null |
| free_shipping | true |
| product_categories | [] |
| excluded_product_categories | [] |
| exclude_sale_items | false |
| minimum_amount | 0.00 |
| maximum_amount | 0.00 |
| email_restrictions | [] |
| used_by | ["1","1"] |
| meta_data | [] |
+-----------------------------+---------------------+
使用 WP CLI 升级数据库
当 WooCommerce 新版本发布时,通常会提示您运行数据库升级。虽然可以通过 WP 管理员界面执行此操作,但高级用户可能更倾向于通过 CLI 运行这些升级,例如,在可能发生超时的繁忙商店中。
要更新数据库,请使用以下 CLI 命令:
$ wp wc update
无需额外参数,且仅会运行待审的升级。更新运行完毕后,将显示新版本。
Marketplace 内容样式指南
本指南提供了在 WooCommerce Marketplace 上创建产品页面和文档的格式和写作标准。遵循这些指南可确保 Marketplace 上的统一性,并为浏览和购买扩展的商家提供专业的体验。
有关产品页面结构、必需元素和资源规范,请参阅 产品页面内容和资源。
写作标准
产品命名规范
在整个产品描述中使用 "Product Name for WooCommerce" 格式,而不是 "WooCommerce Product Name" 格式。
此格式可确保您的产品名称符合 商标规则,并以其唯一标识符开头,从而提高可发现性和清晰度。
语法和标点
请遵循 WooCommerce 语法、标点和首字母大写指南,以获得全面的指导。 关键点包括:
使用牛津逗号,当列出三个或更多项时:
- ✓ "跟踪订单、管理库存和处理退款。"
- ✗ "跟踪订单、管理库存和处理退款。"
尽可能使用主动语态,而不是被动语态:
- ✓ "该扩展在订单发货时发送邮件通知。"
- ✗ "该扩展在订单发货时发送邮件通知。"
首字母大写:
- 对于标题,使用句首大写(仅大写第一个单词和专有名词)
- 不要使用全大写进行强调
- 正确地大写产品名称、功能和 WooCommerce 术语
拼写和术语:
- 使用美式英语拼写
- 使用 "ecommerce"(小写,无连字符)
- 使用 "WooCommerce"(不要使用 "Woocommerce" 或 "wooCommerce")
格式指南
通过遵循以下标准,保持清晰、一致的格式。 自定义样式会干扰 Marketplace 的设计系统,并创建不一致的体验。
文本格式
不要:
- 居中对齐标题或正文
- 更改默认文字颜色
- 添加自定义字体大小或字体
- 过度使用粗体或斜体
可以:
- 在整个文档中使用左对齐文本
- 允许标题和段落继承默认样式
- 仅对关键术语谨慎使用粗体
标题
不要:
- 每个网页包含超过一个 H1 标签(产品标题用作 H1)
- 居中对齐标题
- 对标题应用自定义颜色或样式
可以:
- 使用 H2 作为主要部分
- 使用 H3 作为 H2 部分中的子部分
- 保持逻辑的标题层级结构(不要跳过级别)
章节和布局
请勿:
- 创建自定义样式的章节或容器
- 在章节周围添加边框
- 将背景颜色应用于内容区域
- 添加章节之间的自定义间距
- 添加额外的样式到列
请:
- 使用标准的段落和标题块
- 让 Marketplace 模板处理章节的间距
- 使用默认的列块,不进行样式修改
列表
请勿:
- 使用自定义 CSS 自定义项目符号或编号的设计
- 添加列表项之间的自定义间距
- 创建嵌套列表的深度超过两级
请:
- 使用标准的无序或有序列表块
- 使用批准的列表类来创建带有样式的复选标记(请参见下面的“格式化工具”)
内容限制
表情符号
请勿在产品页面或文档中使用表情符号。表情符号可能导致可访问性问题,在不同设备上的显示不一致,并可能产生不专业的视觉效果。
- ✗ "🚀 提升您的销量!"
- ✓ "提升您的销量"
外部链接
请勿包含指向外部网站的链接。所有支持和文档链接应指向 Marketplace 的 URL:
- 将产品文档的链接指向托管在 WooCommerce.com 上的位置
- 将链接指向 Marketplace 的支持资源
- 请勿链接到外部支持门户、文档网站或着陆页
格式化工具
WooCommerce Marketplace 提供了多种格式化工具,可用于创建具有视觉吸引力的内容,同时保持一致性。
样式化列表类
使用以下 CSS 类来创建专业的复选标记列表:
主要复选标记列表 (wccom-tick-list-primary)
创建带有粗体绿色圆圈的复选标记。用于产品描述顶部的主要优势列表。
<ul class="wccom-tick-list-primary">
<li>支持全球支付</li>
<li>自动计算税费</li>
<li>实时运费计算</li>
</ul>
辅助复选标记列表 (wccom-tick-list-secondary)
创建轻量级的绿色复选标记。用于整个页面的功能列表和辅助内容。
<ul class="wccom-tick-list-secondary">
<li>支持 100 多个货币</li>
<li>符合 PCI 标准</li>
<li>自动更新</li>
</ul>
提示框
使用提示框短代码来突出显示重要信息。可用的样式:
信息提示框
用于提供一般提示和有用的信息:
[box]此扩展程序需要 WooCommerce 8.0 或更高版本。[/box]
此组件可以不带或带有 style="info" 属性使用。
警告提示框 (style="alert")
用于警告或重要通知:
[box style="alert"]在更新到最新版本之前,请备份您的网站。[/box]
错误提示框 (style="error")
用于关键警告或已知限制:
[box style="error"]此扩展程序与多站点安装不兼容。[/box]
成功提示框 (style="success")
用于积极的确认或最佳实践:
[box style="success"]您的 API 凭据已安全加密并存储。</box>
:::info 谨慎使用提示框。过度使用会降低其效果并造成视觉混乱。 :::
文档标准
在为您的产品创建文档时,请遵循以下附加指南:
结构
- 从清晰的介绍开始,解释该扩展程序的作用
- 请使用名为 "Docs – Installation" 的同步模式。这解释了我们的客户如何从 WooCommerce.com 购买和安装产品。
- 记录您产品的所有功能和设置
- 提供常见问题的故障排除指南
有关详细的文档框架,请参阅 支持和文档最佳实践。
图片和截图
在添加视觉内容时:
- 使用现代的 WordPress 管理员配色方案
- 使用最新的 WordPress 核心主题,除非您正在记录不同的主题
- 确保截图清晰易读
- 优化文件大小
- 请勿在截图中包含敏感或个人信息
- 为所有图片添加替代文本,以提高可访问性。
快速入门
我们很高兴您来到这里!WooCommerce.com Marketplace 连接了来自世界各地的可信的开发者和商家,共同创建强大且灵活的在线商店。
为什么您应该在 Woo Marketplace 上销售
- 访问全球范围内的 WooCommerce 商家网络。
- 通过在官方 WooCommerce Marketplace 上列出您的产品,获得内置的品牌认知度和信任度。
- 收入分成模式,旨在支持您的业务增长。
- 机会参与 WooCommerce 的营销活动。
- 从活跃的商家和开发者社区获取信息和反馈。
您是否符合条件?
我们正在寻找以下产品:
协议
要加入 WooCommerce Marketplace,供应商必须提供高质量、安全的产品,提供强大的客户支持,并遵守 WooCommerce 关于列表、更新、定价和沟通的准则。商业条款基于收入分成模式,其中 70% 的销售额归供应商所有。
提交流程
第一步:准备您的产品
第二步:申请加入 Marketplace
提交详细的产品信息、演示链接和测试说明以供审核。
第三步:产品审核
- 我们的团队将审核您的提交,以检查其功能、安全性、兼容性和用户体验。
- 您可能会收到反馈和修改请求。
第四步:发布和销售
- 审核通过后,您的产品将在 WooCommerce.com Marketplace 上列出。
- 发布后,请维护和更新您的产品,并提供持续的商家支持。
有用的资源
准备好申请了吗?
我们期待着帮助您在 WooCommerce 市场中取得成功!
在 Woo Marketplace 中管理产品
在 WooCommerce.com Marketplace 上销售产品的开发者可以编辑他们的产品页面,访问诸如使用数据和销售额等信息,并管理评论。
编辑产品页面
管理产品的大部分工作可以通过 供应商仪表盘 完成。
- 从您的供应商仪表盘,导航到 产品 > 所有产品。
- 选择您要处理的产品。
在那里,您可以查看关于使用的信息,上传新版本,或编辑产品页面。 请查看我们的产品页面指南。

上传新版本
为了维护高质量和具有竞争力的 Marketplace,我们鼓励所有供应商定期更新他们的产品。 持续的更新可以确保与最新版本的 WooCommerce 和 WordPress 的兼容性,提高安全性,并为客户提供持续的价值。
添加或编辑文档
要查看、编辑或添加文档,请在您的供应商仪表盘中导航到 文档。 请查看我们创建有效文档的指南。

了解产品销售额
供应商可以访问有关其产品表现的报告,包括:
- 收入: 新销售额、续费销售额和退款金额。
- 佣金: 供应商从 净 产品销售额中获得的金额。 净收入是指 从扩展购买中收到的收入减去退款、退款、争议、折扣和联盟费用。
- 订阅: 总活动订阅数,包括本月的新订阅和续费订阅,以及退款和续费率。
要查看这些信息,请登录您的供应商仪表盘,并导航到 分析 > 概览。

Marketplace 插件的盈利预期
当您在 Woo Marketplace 上发布插件时,了解我们如何看待盈利方式非常重要。我们的目标是确保您的插件如何产生价值以及如何捕获该价值之间保持一致,从而为商家提供透明的体验,并为开发者建立可持续的合作关系。
:::note 我们目前不接受没有任何盈利途径的免费插件。 必须存在一种盈利途径,要么是插件本身,要么是通过连接到其他付费产品或服务,这些产品或服务将符合以下盈利模式之一。 :::
匹配的盈利模式
您的 Marketplace 插件的盈利模式应反映您的解决方案如何产生收入:
- 独立功能插件: 扩展 WooCommerce 功能且不依赖于外部系统的插件,可以通过标准的 Marketplace 许可模式进行销售,Woo 将直接处理计费。
- 集成插件: 将 WooCommerce 连接到外部服务或平台的插件,需要一种与集成系统向商家计费方式相匹配的盈利方法。
独立插件许可
对于那些向 WooCommerce 添加功能但无需连接到外部服务的插件,我们提供两种列表选项:
付费许可
Marketplace 支持单站点许可模式。 如果您在其他地方销售多站点许可或分级套餐的插件,您的 Marketplace 列表应使用与现有单站点许可费用相近的价格。
免费增值 (Freemium)
如果您的插件提供免费和付费两种版本,您可以将其列为免费增值产品。 这允许商家安装您插件的免费版本,并可以选择升级到付费版本以获得更多功能。 免费增值产品有助于商家在购买前试用,同时让您有机会展示价值并促进升级。
免费增值模式非常适合以下类型的插件:
- 需要另一个插件才能提供升级后的功能
- 核心功能作为免费产品运行良好
- 高级功能提供清晰、可证明的价值,值得升级
- 您希望在转换为付费模式之前建立用户群
集成插件要求
对于将 WooCommerce 与外部系统集成的插件,我们有特定的要求:
优先选择第一方开发
我们强烈建议,与外部系统集成的插件应由拥有或运营该外部系统的公司构建和维护。这可以确保:
- 商家与负责向其收费的公司之间存在直接关系
- 技术支持来自对产品最了解的团队
- 长期维护与外部系统的路线图保持一致
特别是,支付扩展必须由 Woo 或支付提供商直接开发/维护,并符合最低质量标准。
如果您是第三方开发者,正在为您不运营的系统构建集成,我们鼓励您直接与该公司联系,或联系我们的 Marketplace 团队,以讨论您的具体情况。
适当的计费结构
连接到外部计费服务的插件不能使用标准的付费 Marketplace 许可证模式。相反,您必须使用以下选项之一:
| 计费模式 | 描述 | 适用场景 |
|---|---|---|
| 计费 API (推荐) | 我们的 API 代表您的服务处理订阅计费,并提供验证端点以确认付款状态和活动订阅。计费转移到 Woo,您根据收入分成模式获得收益。 查看计费 API 文档 → | 希望 Woo 管理与商家计费关系的 SaaS 提供商。 |
| 合作协议 | 一项协议,该协议扩展了我们的 Marketplace 供应商协议,以适应计费发生在 WooCommerce 之外的解决方案。该插件在 Marketplace 上免费列出。 | 拥有现有计费关系和基础设施的公司。 |
关于合作协议
当计费 API 不适合您的业务模式时,合作协议可作为替代方案。但是,此选项需要正式同意我们的合作条件,并且受我们自行决定的批准。我们评估每个申请,以确保其符合 Marketplace 标准和商家体验期望。
如果您正在考虑此选项,我们建议您在规划过程的早期联系我们的 Marketplace 团队,以讨论资格和要求,然后再投入开发工作。
主题许可
在 Woo Marketplace 上列出的主题仅使用标准的付费许可证模式。计费直接通过 Woo 进行,采用单站点许可证费用。
如果您在其他地方销售您的主题,并提供多站点许可证或分级套餐,您的 Marketplace 列表应使用与您的现有单站点许可证费用相近的价格。
商业服务
商业服务(例如咨询、开发或托管服务)需要在提交之前,获得 Marketplace 团队的正式协议和批准。
如果您提供与 WooCommerce 互补的商业服务,并且希望在 Marketplace 上进行推广,请 联系 Marketplace 团队,讨论您的服务和资格要求。
关于您的计费结构的问题?
如果您不确定哪种盈利模式适用于您的插件、主题或服务,或者您希望在提交审核之前讨论合作选项,请 联系 Marketplace 团队。 我们建议您在规划过程的早期与我们联系,以确保在您投入大量开发工作之前,各项设置能够对齐。
相关资源
- Marketplace 供应商协议 — 所有 Marketplace 供应商的标准条款
- SaaS 产品计费 API — 与我们的计费系统集成的技术文档
- 提交您的产品 — 完整的提交指南
产品更新指南和最佳实践
为了维护一个高质量且具有竞争力的 Marketplace,我们鼓励所有供应商定期更新他们的产品。 持续的更新可以确保与 WooCommerce 和 WordPress 最新版本的兼容性,提高安全性、性能,并为客户提供持续的价值。
最佳实践
简而言 yǎnyin
- 至少每 6 个月更新一次您的产品。
- 与 WooCommerce 核心发布日历 保持一致。
- 使用诸如 质量洞察工具包 (QIT) 和您的 供应商仪表盘 等工具。
- 检查 功能请求门户 以获取产品创意。
- 定期更新 = 更好的客户信任度和续订率。
为什么定期更新很重要
- 兼容性: 确保您的产品与最新的 WooCommerce 和 WordPress 版本无缝协作。
- 安全性: 修复漏洞,并确保客户网站的安全。
- 性能: 提高速度、可靠性和效率。
- 客户信任: 建立对您的品牌和产品持久性的信心。 定期更新的产品通常具有更高的续订率。 每次更新都是提醒客户保持订阅价值的信号。
- 减少支持负担: 通过主动解决问题,减少支持工单的数量。
建议
- 监控 WooCommerce 发布日历: 预测可能影响您产品的更改。
- 收集客户反馈: 利用评论、支持工单和功能请求来改进产品,添加新功能,并解决社区提出的改进建议。
- 使用语义版本控制: 示例:
v2.1.0用于新增功能,v3.0.0用于重大更改。 - 彻底测试: 确保更新稳定且尽可能具有向后兼容性。 考虑将 质量洞察工具 (QIT) 集成到您的工作流程中,以自动检测潜在问题。
- 透明地记录更改: 维护清晰、面向客户的变更日志,如有必要,更新文档和产品页面。
Marketplace 期望
未能跟上 WooCommerce 核心版本或未至少每六个月更新一次的产品将被 标记为从 WooCommerce Marketplace 中移除。
推荐的更新频率
- 主要版本: 至少每季度,以与 WooCommerce 核心版本 保持一致。
- 安全修复: 视情况而定,并应尽快进行。
- 次要改进: 每月或在功能和修复准备就绪时。
- 文档: 确保变更日志和用户指南与每个版本保持同步。
如何部署更新
上传新版本
在上传您扩展的新版本之前,重要的是确保它通过所有 QIT 质量标准。 您可以通过点击 质量洞察 菜单选项,从您的供应商仪表盘运行这些检查。
在您的扩展通过所有 QIT 检查后,您可以上传更新的版本。
点击 版本 选项卡。 您将看到您之前上传的所有版本,以及每个版本的主要变化说明。

点击 添加版本 按钮,然后:
- 选择您想要上传的 .zip 文件,从您的计算机中选择。
- 添加版本号。
- 点击 提交新版本。
提交后,我们将对上传的文件运行以下测试:
所有供应商管理员将在整个过程中收到邮件通知,包括:
- 确认: 当提交新版本时,供应商管理员将收到一封电子邮件,确认该版本已排队。 无需采取任何操作。
- 已拒绝: 如果某个版本未能通过任何自动测试,供应商管理员将收到一封包含具体错误的电子邮件。 开发者应尝试解决该错误,并在准备好时提交新版本。
- 已发布: 如果某个版本通过了自动测试,它将自动部署并对客户可用。 无需采取任何操作。
激活、安全和恶意软件测试的通过是新产品版本部署的必要条件。
格式化更新日志
常见错误
如果上传失败,您应该首先检查以下几个常见错误:
- 文件名: WooCommerce.com 查找您 .zip 文件的特定名称以及其中的主文件夹名称。 当您尝试上传产品时,您将看到预期的名称:

- 存在更新日志: 必须存在一个名为
changelog.txt的文件,用作记录版本之间的更改。 - 无效的更新日志: 提供的
changelog.txt文件不符合预期的格式。 - 版本头信息不匹配: 扩展头信息中的版本号与上传过程中提供版本号不匹配。
- 版本号不匹配: 扩展头信息中的版本号和
changelog.txt中的版本号不匹配。
查看测试结果
自动化测试的结果将显示在 提交测试 表格中,可以通过点击相应的 查看 链接来查看,如以下图片所示:

编程方式上传新版本
要以编程方式部署扩展,必须是扩展的更新,而不是新的提交。 这种方法是另一种替代方案,可以避免登录到供应商仪表盘,并使用用户界面 (UI) 执行相同的操作。
生成应用程序密码
- 确保您已登录到 WooCommerce 供应商仪表盘。
- 创建应用程序密码。
:::note 为了提高安全性,此应用程序密码仅限于部署端点,不能用于代表用户执行任何其他操作。 :::
部署您的产品
向以下 URL 发送 POST 请求,以部署您的产品,使用以下命令:
curl -X POST https://woocommerce.com/wp-json/wc/submission/runner/v1/product/deploy \
-F "file=@/path/to/zip" \
-F "product_id=<product_id>" \
-F "username=<username>" \
-F "password=<app_password>" \
-F "version=<product_version>"
将 <product_id>, <username>, <app_password> 和 <product_version> 替换为您的实际产品 ID、用户名、应用程序密码和产品版本。
检查部署状态
要检查部署状态,请使用以下命令:
curl -X POST https://woocommerce.com/wp-json/wc/submission/runner/v1/product/deploy/status \
-F "product_id=<product_id>" \
-F "username=<username>" \
-F "password=<app_password>"
状态响应
当您查询部署状态时,响应将提供有关进度的详细信息,包括各种测试运行的状态。
以下是响应的示例:
{
"status": "queued",
"version": "1.0.0",
"test_runs": {
"12345": {
"test_run_id": "12345",
"status": "success",
"test_type": "activation",
"result_url": "https://qit.woo.com/?qit_results=12345"
},
"67890": {
"test_run_id": "67890",
"status": "success",
"test_type": "api",
"result_url": "https://qit.woo.com/?qit_results=67890"
}
}
}
注意: 响应中可能包含其他测试运行对象,每个已执行的测试类型对应一个对象。
通过自定义端到端测试最大化兼容性和可靠性
我们强烈鼓励您为基于 QIT 的 自定义端到端测试框架 构建的扩展贡献端到端测试。通过与我们分享这些测试,您在确保不同 WordPress 和 WooCommerce 版本、各种 PHP 环境以及其他流行的扩展之间的真正兼容性方面发挥着至关重要的作用。
我们的自定义端到端测试框架配备了 Docker 化的开发环境和易于使用的命令工具,使您能够设计和执行全面的测试,这些测试使用 Playwright,并且针对您的扩展的独特功能进行定制。
这项举措不仅有助于在潜在的兼容性问题影响用户之前进行缓解,还提高了我们市场中产品的整体可靠性。参与此过程不仅有助于构建一个强大的生态系统,还可以提升您扩展的质量和可靠性声誉。
请查看我们的 QIT 自定义测试文档,以开始利用自定义测试的力量,以确保您的扩展在真实场景中能够无缝运行,并在竞争激烈的市场中脱颖而出。
需要帮助?
如果您需要关于更新计划、QIT 帮助或部署问题的支持,请随时联系 Marketplace 团队。
让我们共同努力,使 WooCommerce.com Marketplace 保持创新、安全和可靠,惠及所有人!
Woo Marketplace 的支持指南
遵守本指南中概述的支持期望是《Marketplace 供应商协议》的强制要求。未能达到这些期望可能导致您的产品从 Marketplace 中暂时或永久移除。
通过参与 WooCommerce.com Marketplace,您不仅仅是在销售一种产品,而是在提供完整的客户体验。提供及时、高质量的支持是该体验的核心,也是建立与客户长期信任的关键因素。
然而,优质的支持不仅是一种要求,更是一个增长的机会。提供卓越的支持可以提高客户忠诚度,增加正面评价,鼓励重复购买,并增强您在 Marketplace 中的声誉,最终有助于您的长期增长和盈利能力。
支持期望
Marketplace 供应商负责按照 WooCommerce 的支持政策提供客户支持,包括:
- 及时回复客户的电子邮件。
- 及时处理客户的评论和评分。
- 管理产品页面上发布的特性请求。
WooCommerce 团队通过管理账户问题、退款、优惠券、升级问题以及实时聊天查询来支持供应商。
响应时间
及时响应至关重要。 如果您不可用或预计出现延迟,请明确告知 WooCommerce 团队,并安排将支持请求正确地转接。
支持评分
客户可以在提交工单后的七 (7) 天后对他们的支持体验进行评分。 保持良好的支持评分对于继续参与 Marketplace 至关重要。
实时聊天
Marketplace 供应商仅通过电子邮件提供支持。 WooCommerce 处理实时聊天查询,并将与产品相关的请求转接到供应商的支持电子邮件地址。
支持的运作方式
工单路由
客户通过支持请求表提交工单,并将自动路由到您指定的支持电子邮件地址。 每封支持电子邮件包含:
- 产品名称
- 订阅日期
- 系统状态报告
- 客户的留言。
指定您的支持电子邮件地址
您可以在供应商仪表盘的 设置 > 商店 中指定应将支持工单路由到的电子邮件地址。 WooCommerce 团队还将使用此地址将您抄送 (CC) 到工单中。
:::note “支持电子邮件”字段与用于订单通知的“联系电子邮件”字段不同。 :::

设置支持工单回复
- 激活自动回复器: 自动告知客户您已收到他们的请求,并提供指向您的隐私和数据使用政策的链接。 避免使用促销或联盟链接。
- 停用任何平台反馈请求: 客户已经从 Woo Marketplace 直接收到反馈请求。
安全性和客户登录凭证
如果您需要登录商家的店铺以成功地为他们提供帮助,请遵循以下指南:
- 只有在尝试了所有其他选项后,才要求提供登录凭证。 这包括要求提供截图并在您自己的测试站点上重现问题。
- 在要求提供登录凭证时:
- 告知客户,根据 GDPR 规定,他们需要在店铺的条款和条件中说明他们可能需要向第三方支持服务提供访问权限。
- 始终要求客户为您创建一个临时管理员帐户。(您需要修改上面链接的文档中的说明,因为您无法访问
woologin@woocommerce.com。) - 在支持交互结束时,请要求商家删除此临时帐户。
- 如果客户在您提供上述说明之前分享了他们的详细信息, 始终指出他们最好不要这样做,并且您强烈建议他们重置密码。
- 切勿要求提供明文密码。 而是使用密码共享服务,例如 QuickForget.com,以创建唯一的、具有过期时间的链接。
协作、退款和升级
要与其他 Marketplace 供应商合作,您可以在支持工单中抄送 (CC) 相关方。其他供应商的联系方式可从 WooCommerce 团队获取。
所有退款、优惠券和升级都由 WooCommerce 管理。请将相关工单转发给 Marketplace Developer P2 的私有 Email 地址,抄送即可。
Marketplace 支持工具
订阅状态检查
订阅详细信息包含在客户支持邮件中。您可以通过供应商仪表盘中的 设置 > 工具 进行其他检查。

评论和评分
供应商应监控和回复客户的评分和评论,这是他们支持职责的一部分。及时解决问题不仅可以提高客户满意度,还可以表明您致力于提供优质服务。
请记住,如果客户获得了有帮助且及时的支持体验,他们更有可能留下积极的评论。积极地与客户反馈互动——无论是赞扬还是批评——可以增强您的产品声誉并培养长期信任。
您产品的评论和评分通过您的供应商仪表盘进行管理。

功能请求
客户可以通过您的产品网页提交功能请求。这些请求是公开可见的,并能提供宝贵的洞察,了解用户希望您的产品具备哪些功能。
供应商应定期监控和回复这些请求,就像处理其他支持渠道一样。及时、周到的回复对于功能请求,表明您重视用户的反馈,并且正在积极努力改进您的产品。
功能请求是了解客户如何使用您的产品、识别常见问题以及制定产品路线图的强大工具。通过参与这些讨论,您可以建立信任,并与客户不断变化的需求保持一致。
您产品的功能请求通过供应商仪表盘中的“功能请求”进行管理。
