
本文详解如何在 woocommerce 多供应商环境(如 wcfm 插件)中,按供应商 id 对订单内商品进行精准分组,并汇总各供应商对应的商品销售总额。
本文详解如何在 woocommerce 多供应商环境(如 wcfm 插件)中,按供应商 id 对订单内商品进行精准分组,并汇总各供应商对应的商品销售总额。
在 WooCommerce 多供应商(Multi-Vendor)场景下,一个订单常包含多个不同供应商的商品。若需按供应商维度统计销售额(例如结算、佣金计算或后台报表),核心挑战在于:正确将订单中的每个商品项映射到其所属供应商,并按供应商聚合商品价格。常见错误(如原问题代码所示)在于使用 $vendor_items_map[$vendor] = $product_ids 进行简单赋值,导致后写入的 product_id 覆盖前值,无法形成多值数组。
✅ 正确实现逻辑:分组 → 汇总 → 输出
我们采用三步法:
- 遍历订单商品项,获取每个商品 ID 及其归属的供应商 ID;
- 以供应商 ID 为键,动态追加商品 ID 到二维数组(关键!用 $array[$key][] = $value 语法);
- 再次遍历分组结果,累加各商品的行项目价格($item->get_total()),得到最终的供应商销售额映射。
以下是完整、健壮、可直接集成的 PHP 示例代码(兼容 WCFM 插件):
function get_vendor_wise_order_revenue( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) {
return [];
}
$vendor_items_map = []; // 存储 vendor_id => [product_id1, product_id2, ...]
$vendor_revenue_map = []; // 存储 vendor_id => total_revenue
foreach ( $order->get_items() as $item ) {
$product_id = $item->get_product_id();
$vendor_id = wcfm_get_vendor_id_by_post( $product_id );
// 安全检查:确保获取到有效供应商 ID(避免空/0/非法值)
if ( ! $vendor_id || ! is_numeric( $vendor_id ) ) {
continue;
}
// ✅ 关键:使用 [] 语法追加,而非覆盖赋值
$vendor_items_map[ $vendor_id ][] = $product_id;
// 同时累加该商品行总价(含税费已计入 get_total)
$vendor_revenue_map[ $vendor_id ] = ( $vendor_revenue_map[ $vendor_id ] ?? 0 ) + $item->get_total();
}
// 【可选】补充:若需返回详细商品列表 + 总价,可重构为关联结构
$result = [];
foreach ( $vendor_items_map as $vid => $pids ) {
$result[ $vid ] = [
'product_ids' => $pids,
'revenue' => wc_price( $vendor_revenue_map[ $vid ] ),
'raw_amount' => $vendor_revenue_map[ $vid ],
];
}
return $result;
}
// 使用示例
$revenue_data = get_vendor_wise_order_revenue(18154);
print_r($revenue_data);输出示例(格式化后):
Array
(
[20] => Array
(
[product_ids] => Array([0] => 1340, [1] => 1345)
[revenue] => ¥30.00
[raw_amount] => 30.00
)
[30] => Array
(
[product_ids] => Array([0] => 1350)
[revenue] => ¥40.00
[raw_amount] => 40.00
)
)⚠️ 注意事项与最佳实践
- 避免 get_items() 中使用过时的数组访问方式:原代码中 $item['product_id'] 已不推荐(WooCommerce 3.0+ 应使用面向对象方法 $item->get_product_id()),确保兼容性与类型安全;
- 供应商 ID 验证不可省略:wcfm_get_vendor_id_by_post() 在商品未绑定供应商或插件异常时可能返回 false/null,务必做空值判断;
- 价格取值应使用 $item->get_total():它返回该商品行的最终结算价(含数量 × 单价 ± 折扣),比手动查 $product->get_price() 更准确;
- 如需支持变体商品:$item->get_variation_id() 可用于识别具体变体,但供应商通常绑定在父商品(post_parent),逻辑一致;
- 性能提示:单次订单处理无需缓存,但若批量处理(如导出报表),建议结合 WC_Order_Item 数据库查询优化。
通过以上方案,你不仅能精准实现 20 => [1340, 1345] 的分组目标,更能一步到位获得各供应商的实时销售业绩,为多供应商结算、数据看板及自动化分账打下坚实基础。










